diff --git a/audio/die/dc_sb_lusu_shadow.mp3 b/audio/die/dc_sb_lusu_shadow.mp3
new file mode 100644
index 000000000..c7411b2c1
Binary files /dev/null and b/audio/die/dc_sb_lusu_shadow.mp3 differ
diff --git a/audio/die/dongzhuo.mp3 b/audio/die/dongzhuo.mp3
index 5c82b9519..a5daa22e0 100644
Binary files a/audio/die/dongzhuo.mp3 and b/audio/die/dongzhuo.mp3 differ
diff --git a/audio/die/guansuo.mp3 b/audio/die/guansuo.mp3
new file mode 100644
index 000000000..0f458b2a9
Binary files /dev/null and b/audio/die/guansuo.mp3 differ
diff --git a/audio/die/gz_jun_caocao.mp3 b/audio/die/gz_jun_caocao.mp3
index c0b5635cf..59e6fc3fa 100644
Binary files a/audio/die/gz_jun_caocao.mp3 and b/audio/die/gz_jun_caocao.mp3 differ
diff --git a/audio/die/gz_jun_liubei.mp3 b/audio/die/gz_jun_liubei.mp3
index 7f6df894f..6c640901b 100644
Binary files a/audio/die/gz_jun_liubei.mp3 and b/audio/die/gz_jun_liubei.mp3 differ
diff --git a/audio/die/gz_jun_sunquan.mp3 b/audio/die/gz_jun_sunquan.mp3
index d4a5a8887..c908f14fb 100644
Binary files a/audio/die/gz_jun_sunquan.mp3 and b/audio/die/gz_jun_sunquan.mp3 differ
diff --git a/audio/die/gz_jun_zhangjiao.mp3 b/audio/die/gz_jun_zhangjiao.mp3
index 0d8718f52..86eda53ff 100644
Binary files a/audio/die/gz_jun_zhangjiao.mp3 and b/audio/die/gz_jun_zhangjiao.mp3 differ
diff --git a/audio/die/old_huaxiong.mp3 b/audio/die/old_huaxiong.mp3
new file mode 100644
index 000000000..ad106265f
Binary files /dev/null and b/audio/die/old_huaxiong.mp3 differ
diff --git a/audio/die/old_zhoutai.mp3 b/audio/die/old_zhoutai.mp3
new file mode 100644
index 000000000..80ff4c06b
Binary files /dev/null and b/audio/die/old_zhoutai.mp3 differ
diff --git a/audio/die/re_lusu.mp3 b/audio/die/re_lusu.mp3
index af954c290..91e4d771f 100644
Binary files a/audio/die/re_lusu.mp3 and b/audio/die/re_lusu.mp3 differ
diff --git a/audio/die/re_yuji.mp3 b/audio/die/re_yuji.mp3
index 9546a33de..4cc88e36f 100755
Binary files a/audio/die/re_yuji.mp3 and b/audio/die/re_yuji.mp3 differ
diff --git a/audio/die/ol_masu.mp3 b/audio/die/xin_masu.mp3
similarity index 100%
rename from audio/die/ol_masu.mp3
rename to audio/die/xin_masu.mp3
diff --git a/audio/die/xin_sunquan.mp3 b/audio/die/xin_sunquan.mp3
new file mode 100644
index 000000000..cb394a8a9
Binary files /dev/null and b/audio/die/xin_sunquan.mp3 differ
diff --git a/audio/die/xusheng.mp3 b/audio/die/xusheng.mp3
index f3bc95b4c..baa93f73c 100644
Binary files a/audio/die/xusheng.mp3 and b/audio/die/xusheng.mp3 differ
diff --git a/audio/die/yadan.mp3 b/audio/die/yadan.mp3
new file mode 100644
index 000000000..44086d0ee
Binary files /dev/null and b/audio/die/yadan.mp3 differ
diff --git a/audio/die/yue_miheng.mp3 b/audio/die/yue_miheng.mp3
new file mode 100644
index 000000000..aa7d85f80
Binary files /dev/null and b/audio/die/yue_miheng.mp3 differ
diff --git a/audio/die/zhangren.mp3 b/audio/die/zhangren.mp3
index 803f185c2..63718afc8 100644
Binary files a/audio/die/zhangren.mp3 and b/audio/die/zhangren.mp3 differ
diff --git a/audio/skill/baonue21.mp3 b/audio/skill/baonue21.mp3
index ae0f9e6b0..36060c9b6 100755
Binary files a/audio/skill/baonue21.mp3 and b/audio/skill/baonue21.mp3 differ
diff --git a/audio/skill/baonue22.mp3 b/audio/skill/baonue22.mp3
index 81e966def..8a75b0507 100755
Binary files a/audio/skill/baonue22.mp3 and b/audio/skill/baonue22.mp3 differ
diff --git a/audio/skill/benghuai_zhugedan2.mp3 b/audio/skill/benghuai_zhugedan2.mp3
deleted file mode 100644
index 3efb18bf6..000000000
Binary files a/audio/skill/benghuai_zhugedan2.mp3 and /dev/null differ
diff --git a/audio/skill/dangxian_guansuo2.mp3 b/audio/skill/dangxian_guansuo2.mp3
deleted file mode 100644
index 1742c18e3..000000000
Binary files a/audio/skill/dangxian_guansuo2.mp3 and /dev/null differ
diff --git a/audio/skill/dchuanli1.mp3 b/audio/skill/dchuanli1.mp3
new file mode 100644
index 000000000..d27041202
Binary files /dev/null and b/audio/skill/dchuanli1.mp3 differ
diff --git a/audio/skill/dchuanli2.mp3 b/audio/skill/dchuanli2.mp3
new file mode 100644
index 000000000..1175bb5b5
Binary files /dev/null and b/audio/skill/dchuanli2.mp3 differ
diff --git a/audio/skill/dchuiwan1.mp3 b/audio/skill/dchuiwan1.mp3
new file mode 100644
index 000000000..68439a186
Binary files /dev/null and b/audio/skill/dchuiwan1.mp3 differ
diff --git a/audio/skill/dchuiwan2.mp3 b/audio/skill/dchuiwan2.mp3
new file mode 100644
index 000000000..7f82be918
Binary files /dev/null and b/audio/skill/dchuiwan2.mp3 differ
diff --git a/audio/skill/dcjigu1.mp3 b/audio/skill/dcjigu1.mp3
new file mode 100644
index 000000000..cfebca8cb
Binary files /dev/null and b/audio/skill/dcjigu1.mp3 differ
diff --git a/audio/skill/dcjigu2.mp3 b/audio/skill/dcjigu2.mp3
new file mode 100644
index 000000000..ef3691bcc
Binary files /dev/null and b/audio/skill/dcjigu2.mp3 differ
diff --git a/audio/skill/dcsbmengmou1.mp3 b/audio/skill/dcsbmengmou1.mp3
index d548d3e0b..13a71dfb3 100644
Binary files a/audio/skill/dcsbmengmou1.mp3 and b/audio/skill/dcsbmengmou1.mp3 differ
diff --git a/audio/skill/dcsbmengmou2.mp3 b/audio/skill/dcsbmengmou2.mp3
index d5288680b..17fa3ea15 100644
Binary files a/audio/skill/dcsbmengmou2.mp3 and b/audio/skill/dcsbmengmou2.mp3 differ
diff --git a/audio/skill/dcsbmengmou_dc_sb_lusu_shadow1.mp3 b/audio/skill/dcsbmengmou_dc_sb_lusu_shadow1.mp3
new file mode 100644
index 000000000..d548d3e0b
Binary files /dev/null and b/audio/skill/dcsbmengmou_dc_sb_lusu_shadow1.mp3 differ
diff --git a/audio/skill/dcsbmengmou_dc_sb_lusu_shadow2.mp3 b/audio/skill/dcsbmengmou_dc_sb_lusu_shadow2.mp3
new file mode 100644
index 000000000..d5288680b
Binary files /dev/null and b/audio/skill/dcsbmengmou_dc_sb_lusu_shadow2.mp3 differ
diff --git a/audio/skill/dcsbmingshi_dc_sb_lusu_shadow1.mp3 b/audio/skill/dcsbmingshi_dc_sb_lusu_shadow1.mp3
new file mode 100644
index 000000000..887701248
Binary files /dev/null and b/audio/skill/dcsbmingshi_dc_sb_lusu_shadow1.mp3 differ
diff --git a/audio/skill/dcsbmingshi_dc_sb_lusu_shadow2.mp3 b/audio/skill/dcsbmingshi_dc_sb_lusu_shadow2.mp3
new file mode 100644
index 000000000..00b5c82ac
Binary files /dev/null and b/audio/skill/dcsbmingshi_dc_sb_lusu_shadow2.mp3 differ
diff --git a/audio/skill/dcsirui1.mp3 b/audio/skill/dcsirui1.mp3
new file mode 100644
index 000000000..2e5a6b7a5
Binary files /dev/null and b/audio/skill/dcsirui1.mp3 differ
diff --git a/audio/skill/dcsirui2.mp3 b/audio/skill/dcsirui2.mp3
new file mode 100644
index 000000000..90c80c293
Binary files /dev/null and b/audio/skill/dcsirui2.mp3 differ
diff --git a/audio/skill/dcsuchou1.mp3 b/audio/skill/dcsuchou1.mp3
new file mode 100644
index 000000000..38e2db983
Binary files /dev/null and b/audio/skill/dcsuchou1.mp3 differ
diff --git a/audio/skill/dcsuchou2.mp3 b/audio/skill/dcsuchou2.mp3
new file mode 100644
index 000000000..56f4aed79
Binary files /dev/null and b/audio/skill/dcsuchou2.mp3 differ
diff --git a/audio/skill/gz_jun_liubei.mp3 b/audio/skill/gz_jun_liubei.mp3
deleted file mode 100644
index 4afa753ae..000000000
Binary files a/audio/skill/gz_jun_liubei.mp3 and /dev/null differ
diff --git a/audio/skill/gz_jun_sunquan.mp3 b/audio/skill/gz_jun_sunquan.mp3
deleted file mode 100644
index fb8447894..000000000
Binary files a/audio/skill/gz_jun_sunquan.mp3 and /dev/null differ
diff --git a/audio/skill/gzzongyu1.mp3 b/audio/skill/gzzongyu1.mp3
index dc10d827b..fc2c57387 100644
Binary files a/audio/skill/gzzongyu1.mp3 and b/audio/skill/gzzongyu1.mp3 differ
diff --git a/audio/skill/gzzongyu2.mp3 b/audio/skill/gzzongyu2.mp3
index 7e8430de5..0978b5013 100644
Binary files a/audio/skill/gzzongyu2.mp3 and b/audio/skill/gzzongyu2.mp3 differ
diff --git a/audio/skill/hongfa1.mp3 b/audio/skill/hongfa1.mp3
index 2eb98486d..28f40d4b7 100644
Binary files a/audio/skill/hongfa1.mp3 and b/audio/skill/hongfa1.mp3 differ
diff --git a/audio/skill/hongfa2.mp3 b/audio/skill/hongfa2.mp3
index 7e32a02be..cb39444d6 100644
Binary files a/audio/skill/hongfa2.mp3 and b/audio/skill/hongfa2.mp3 differ
diff --git a/audio/skill/hongfa3.mp3 b/audio/skill/hongfa3.mp3
new file mode 100644
index 000000000..9dc1b1f7b
Binary files /dev/null and b/audio/skill/hongfa3.mp3 differ
diff --git a/audio/skill/hongfa_hp.mp3 b/audio/skill/hongfa_hp.mp3
deleted file mode 100644
index a5d03b163..000000000
Binary files a/audio/skill/hongfa_hp.mp3 and /dev/null differ
diff --git a/audio/skill/huangjintianbingfu1.mp3 b/audio/skill/huangjintianbingfu1.mp3
index 731c1cc68..3017436ed 100644
Binary files a/audio/skill/huangjintianbingfu1.mp3 and b/audio/skill/huangjintianbingfu1.mp3 differ
diff --git a/audio/skill/huangjintianbingfu2.mp3 b/audio/skill/huangjintianbingfu2.mp3
index 97685de68..45c554042 100644
Binary files a/audio/skill/huangjintianbingfu2.mp3 and b/audio/skill/huangjintianbingfu2.mp3 differ
diff --git a/audio/skill/huangjintianbingfu3.mp3 b/audio/skill/huangjintianbingfu3.mp3
new file mode 100644
index 000000000..8b963aeef
Binary files /dev/null and b/audio/skill/huangjintianbingfu3.mp3 differ
diff --git a/audio/skill/huibian1.mp3 b/audio/skill/huibian1.mp3
index 861317d59..5933267db 100644
Binary files a/audio/skill/huibian1.mp3 and b/audio/skill/huibian1.mp3 differ
diff --git a/audio/skill/huibian2.mp3 b/audio/skill/huibian2.mp3
index f9dfa9686..df26af56b 100644
Binary files a/audio/skill/huibian2.mp3 and b/audio/skill/huibian2.mp3 differ
diff --git a/audio/skill/jiahe.mp3 b/audio/skill/jiahe.mp3
new file mode 100644
index 000000000..c15b99f82
Binary files /dev/null and b/audio/skill/jiahe.mp3 differ
diff --git a/audio/skill/jiahe1.mp3 b/audio/skill/jiahe1.mp3
deleted file mode 100644
index fa94929d1..000000000
Binary files a/audio/skill/jiahe1.mp3 and /dev/null differ
diff --git a/audio/skill/jiahe2.mp3 b/audio/skill/jiahe2.mp3
deleted file mode 100644
index a35b153c1..000000000
Binary files a/audio/skill/jiahe2.mp3 and /dev/null differ
diff --git a/audio/skill/jiahe_duoshi1.mp3 b/audio/skill/jiahe_duoshi1.mp3
new file mode 100644
index 000000000..5e1902f17
Binary files /dev/null and b/audio/skill/jiahe_duoshi1.mp3 differ
diff --git a/audio/skill/jiahe_duoshi2.mp3 b/audio/skill/jiahe_duoshi2.mp3
new file mode 100644
index 000000000..afdd9d8d5
Binary files /dev/null and b/audio/skill/jiahe_duoshi2.mp3 differ
diff --git a/audio/skill/jiahe_haoshi1.mp3 b/audio/skill/jiahe_haoshi1.mp3
new file mode 100644
index 000000000..95049ba05
Binary files /dev/null and b/audio/skill/jiahe_haoshi1.mp3 differ
diff --git a/audio/skill/jiahe_haoshi2.mp3 b/audio/skill/jiahe_haoshi2.mp3
new file mode 100644
index 000000000..63d42993b
Binary files /dev/null and b/audio/skill/jiahe_haoshi2.mp3 differ
diff --git a/audio/skill/jiahe_put1.mp3 b/audio/skill/jiahe_put1.mp3
deleted file mode 100644
index 0d338298c..000000000
Binary files a/audio/skill/jiahe_put1.mp3 and /dev/null differ
diff --git a/audio/skill/jiahe_put2.mp3 b/audio/skill/jiahe_put2.mp3
deleted file mode 100644
index 84f321534..000000000
Binary files a/audio/skill/jiahe_put2.mp3 and /dev/null differ
diff --git a/audio/skill/jiahe_reyingzi1.mp3 b/audio/skill/jiahe_reyingzi1.mp3
new file mode 100644
index 000000000..960f2f3bd
Binary files /dev/null and b/audio/skill/jiahe_reyingzi1.mp3 differ
diff --git a/audio/skill/jiahe_reyingzi2.mp3 b/audio/skill/jiahe_reyingzi2.mp3
new file mode 100644
index 000000000..63af9169e
Binary files /dev/null and b/audio/skill/jiahe_reyingzi2.mp3 differ
diff --git a/audio/skill/jiahe_shelie1.mp3 b/audio/skill/jiahe_shelie1.mp3
new file mode 100644
index 000000000..6ebce8b83
Binary files /dev/null and b/audio/skill/jiahe_shelie1.mp3 differ
diff --git a/audio/skill/jiahe_shelie2.mp3 b/audio/skill/jiahe_shelie2.mp3
new file mode 100644
index 000000000..3a82a5829
Binary files /dev/null and b/audio/skill/jiahe_shelie2.mp3 differ
diff --git a/audio/skill/jianan.mp3 b/audio/skill/jianan.mp3
new file mode 100644
index 000000000..28a8c67d5
Binary files /dev/null and b/audio/skill/jianan.mp3 differ
diff --git a/audio/skill/jianan1.mp3 b/audio/skill/jianan1.mp3
deleted file mode 100644
index 72931e407..000000000
Binary files a/audio/skill/jianan1.mp3 and /dev/null differ
diff --git a/audio/skill/jianan2.mp3 b/audio/skill/jianan2.mp3
deleted file mode 100644
index b44a3c311..000000000
Binary files a/audio/skill/jianan2.mp3 and /dev/null differ
diff --git a/audio/skill/jianan_duanliang.mp3 b/audio/skill/jianan_duanliang.mp3
new file mode 100644
index 000000000..966551538
Binary files /dev/null and b/audio/skill/jianan_duanliang.mp3 differ
diff --git a/audio/skill/jianan_jieyue.mp3 b/audio/skill/jianan_jieyue.mp3
new file mode 100644
index 000000000..899707f0f
Binary files /dev/null and b/audio/skill/jianan_jieyue.mp3 differ
diff --git a/audio/skill/jianan_qiaobian.mp3 b/audio/skill/jianan_qiaobian.mp3
new file mode 100644
index 000000000..e7f2946a2
Binary files /dev/null and b/audio/skill/jianan_qiaobian.mp3 differ
diff --git a/audio/skill/jianan_tuxi.mp3 b/audio/skill/jianan_tuxi.mp3
new file mode 100644
index 000000000..779205f9e
Binary files /dev/null and b/audio/skill/jianan_tuxi.mp3 differ
diff --git a/audio/skill/jianan_xiaoguo.mp3 b/audio/skill/jianan_xiaoguo.mp3
new file mode 100644
index 000000000..d53775518
Binary files /dev/null and b/audio/skill/jianan_xiaoguo.mp3 differ
diff --git a/audio/skill/jijiang1_liushan1.mp3 b/audio/skill/jijiang1_liushan1.mp3
index 77453e1df..5a8a48000 100755
Binary files a/audio/skill/jijiang1_liushan1.mp3 and b/audio/skill/jijiang1_liushan1.mp3 differ
diff --git a/audio/skill/jijiang1_liushan2.mp3 b/audio/skill/jijiang1_liushan2.mp3
index a22276a0d..c5dbd42bb 100755
Binary files a/audio/skill/jijiang1_liushan2.mp3 and b/audio/skill/jijiang1_liushan2.mp3 differ
diff --git a/audio/skill/jiuchi1.mp3 b/audio/skill/jiuchi1.mp3
index b977881be..e03df6994 100755
Binary files a/audio/skill/jiuchi1.mp3 and b/audio/skill/jiuchi1.mp3 differ
diff --git a/audio/skill/jiuchi2.mp3 b/audio/skill/jiuchi2.mp3
index cbe30c780..729947703 100755
Binary files a/audio/skill/jiuchi2.mp3 and b/audio/skill/jiuchi2.mp3 differ
diff --git a/audio/skill/jizhao1.mp3 b/audio/skill/jizhao1.mp3
index be9d096aa..3f32e309c 100644
Binary files a/audio/skill/jizhao1.mp3 and b/audio/skill/jizhao1.mp3 differ
diff --git a/audio/skill/jizhao2.mp3 b/audio/skill/jizhao2.mp3
index 5608eebcc..1541ba499 100644
Binary files a/audio/skill/jizhao2.mp3 and b/audio/skill/jizhao2.mp3 differ
diff --git a/audio/skill/jubao1.mp3 b/audio/skill/jubao1.mp3
index d40da57b1..56b0618b4 100644
Binary files a/audio/skill/jubao1.mp3 and b/audio/skill/jubao1.mp3 differ
diff --git a/audio/skill/jubao2.mp3 b/audio/skill/jubao2.mp3
index cd5f425fc..693162d8b 100644
Binary files a/audio/skill/jubao2.mp3 and b/audio/skill/jubao2.mp3 differ
diff --git a/audio/skill/juyi2.mp3 b/audio/skill/juyi2.mp3
deleted file mode 100644
index 1b956d9f0..000000000
Binary files a/audio/skill/juyi2.mp3 and /dev/null differ
diff --git a/audio/skill/kunfen_ol_sb_jiangwei1.mp3 b/audio/skill/kunfen_ol_sb_jiangwei1.mp3
new file mode 100644
index 000000000..eba15aeca
Binary files /dev/null and b/audio/skill/kunfen_ol_sb_jiangwei1.mp3 differ
diff --git a/audio/skill/lianzi1.mp3 b/audio/skill/lianzi1.mp3
index 2d9a60099..e37e07a2c 100644
Binary files a/audio/skill/lianzi1.mp3 and b/audio/skill/lianzi1.mp3 differ
diff --git a/audio/skill/lianzi2.mp3 b/audio/skill/lianzi2.mp3
index 73475b7a1..453111acf 100644
Binary files a/audio/skill/lianzi2.mp3 and b/audio/skill/lianzi2.mp3 differ
diff --git a/audio/skill/olqingya1.mp3 b/audio/skill/olqingya1.mp3
new file mode 100644
index 000000000..52a2f4bbb
Binary files /dev/null and b/audio/skill/olqingya1.mp3 differ
diff --git a/audio/skill/olqingya2.mp3 b/audio/skill/olqingya2.mp3
new file mode 100644
index 000000000..c863dec1c
Binary files /dev/null and b/audio/skill/olqingya2.mp3 differ
diff --git a/audio/skill/paoxiao_guanzhang2.mp3 b/audio/skill/paoxiao_guanzhang2.mp3
deleted file mode 100644
index ed36d145f..000000000
Binary files a/audio/skill/paoxiao_guanzhang2.mp3 and /dev/null differ
diff --git a/audio/skill/rerende_gz_jun_liubei1.mp3 b/audio/skill/rerende_gz_jun_liubei1.mp3
index 527bdb7db..c643840c2 100644
Binary files a/audio/skill/rerende_gz_jun_liubei1.mp3 and b/audio/skill/rerende_gz_jun_liubei1.mp3 differ
diff --git a/audio/skill/rerende_gz_jun_liubei2.mp3 b/audio/skill/rerende_gz_jun_liubei2.mp3
index 6231d8217..36c4fa9e2 100644
Binary files a/audio/skill/rerende_gz_jun_liubei2.mp3 and b/audio/skill/rerende_gz_jun_liubei2.mp3 differ
diff --git a/audio/skill/roulin1.mp3 b/audio/skill/roulin1.mp3
index df5599294..1aa8a32a3 100755
Binary files a/audio/skill/roulin1.mp3 and b/audio/skill/roulin1.mp3 differ
diff --git a/audio/skill/roulin2.mp3 b/audio/skill/roulin2.mp3
index 6c6565ad7..d29200839 100755
Binary files a/audio/skill/roulin2.mp3 and b/audio/skill/roulin2.mp3 differ
diff --git a/audio/skill/shouyue.mp3 b/audio/skill/shouyue.mp3
new file mode 100644
index 000000000..405922bc8
Binary files /dev/null and b/audio/skill/shouyue.mp3 differ
diff --git a/audio/skill/shouyue_liegong1.mp3 b/audio/skill/shouyue_liegong1.mp3
new file mode 100644
index 000000000..9ebe3ff05
Binary files /dev/null and b/audio/skill/shouyue_liegong1.mp3 differ
diff --git a/audio/skill/shouyue_liegong2.mp3 b/audio/skill/shouyue_liegong2.mp3
new file mode 100644
index 000000000..1d6cadb84
Binary files /dev/null and b/audio/skill/shouyue_liegong2.mp3 differ
diff --git a/audio/skill/shouyue_longdan1.mp3 b/audio/skill/shouyue_longdan1.mp3
new file mode 100644
index 000000000..8fcf94e9d
Binary files /dev/null and b/audio/skill/shouyue_longdan1.mp3 differ
diff --git a/audio/skill/shouyue_longdan2.mp3 b/audio/skill/shouyue_longdan2.mp3
new file mode 100644
index 000000000..f93155870
Binary files /dev/null and b/audio/skill/shouyue_longdan2.mp3 differ
diff --git a/audio/skill/shouyue_paoxiao1.mp3 b/audio/skill/shouyue_paoxiao1.mp3
new file mode 100644
index 000000000..fae998a18
Binary files /dev/null and b/audio/skill/shouyue_paoxiao1.mp3 differ
diff --git a/audio/skill/shouyue_paoxiao2.mp3 b/audio/skill/shouyue_paoxiao2.mp3
new file mode 100644
index 000000000..da28a31e1
Binary files /dev/null and b/audio/skill/shouyue_paoxiao2.mp3 differ
diff --git a/audio/skill/shouyue_tieji1.mp3 b/audio/skill/shouyue_tieji1.mp3
new file mode 100644
index 000000000..a568032f5
Binary files /dev/null and b/audio/skill/shouyue_tieji1.mp3 differ
diff --git a/audio/skill/shouyue_tieji2.mp3 b/audio/skill/shouyue_tieji2.mp3
new file mode 100644
index 000000000..99bc5f5e5
Binary files /dev/null and b/audio/skill/shouyue_tieji2.mp3 differ
diff --git a/audio/skill/shouyue_wusheng1.mp3 b/audio/skill/shouyue_wusheng1.mp3
new file mode 100644
index 000000000..6a3a39c23
Binary files /dev/null and b/audio/skill/shouyue_wusheng1.mp3 differ
diff --git a/audio/skill/shouyue_wusheng2.mp3 b/audio/skill/shouyue_wusheng2.mp3
new file mode 100644
index 000000000..fee31f044
Binary files /dev/null and b/audio/skill/shouyue_wusheng2.mp3 differ
diff --git a/audio/skill/weizhong2.mp3 b/audio/skill/weizhong2.mp3
deleted file mode 100644
index 5db1df8c5..000000000
Binary files a/audio/skill/weizhong2.mp3 and /dev/null differ
diff --git a/audio/skill/wendao1.mp3 b/audio/skill/wendao1.mp3
index 5052e5dbd..be1087889 100644
Binary files a/audio/skill/wendao1.mp3 and b/audio/skill/wendao1.mp3 differ
diff --git a/audio/skill/wendao2.mp3 b/audio/skill/wendao2.mp3
index 8ad7204e4..b08680923 100644
Binary files a/audio/skill/wendao2.mp3 and b/audio/skill/wendao2.mp3 differ
diff --git a/audio/skill/wusheng_guansuo2.mp3 b/audio/skill/wusheng_guansuo2.mp3
deleted file mode 100644
index 58c8bef69..000000000
Binary files a/audio/skill/wusheng_guansuo2.mp3 and /dev/null differ
diff --git a/audio/skill/wusheng_guanzhang2.mp3 b/audio/skill/wusheng_guanzhang2.mp3
deleted file mode 100644
index d8d28344d..000000000
Binary files a/audio/skill/wusheng_guanzhang2.mp3 and /dev/null differ
diff --git a/audio/skill/wuxin1.mp3 b/audio/skill/wuxin1.mp3
index a22eff2fe..dc4d017b2 100644
Binary files a/audio/skill/wuxin1.mp3 and b/audio/skill/wuxin1.mp3 differ
diff --git a/audio/skill/wuxin2.mp3 b/audio/skill/wuxin2.mp3
index ed10c44ed..23cee2e7d 100644
Binary files a/audio/skill/wuxin2.mp3 and b/audio/skill/wuxin2.mp3 differ
diff --git a/audio/skill/wuziliangjiangdao1.mp3 b/audio/skill/wuziliangjiangdao1.mp3
new file mode 100644
index 000000000..e3d2832dc
Binary files /dev/null and b/audio/skill/wuziliangjiangdao1.mp3 differ
diff --git a/audio/skill/wuziliangjiangdao2.mp3 b/audio/skill/wuziliangjiangdao2.mp3
new file mode 100644
index 000000000..5fab6078e
Binary files /dev/null and b/audio/skill/wuziliangjiangdao2.mp3 differ
diff --git a/audio/skill/xinfu_xingzhao1.mp3 b/audio/skill/xinfu_xingzhao1.mp3
new file mode 100644
index 000000000..2321cd55a
Binary files /dev/null and b/audio/skill/xinfu_xingzhao1.mp3 differ
diff --git a/audio/skill/xinfu_xingzhao2.mp3 b/audio/skill/xinfu_xingzhao2.mp3
index 737246af0..73db5c4ec 100644
Binary files a/audio/skill/xinfu_xingzhao2.mp3 and b/audio/skill/xinfu_xingzhao2.mp3 differ
diff --git a/audio/skill/xz_xunxun1.mp3 b/audio/skill/xz_xunxun1.mp3
index 73db5c4ec..a374db5e1 100644
Binary files a/audio/skill/xz_xunxun1.mp3 and b/audio/skill/xz_xunxun1.mp3 differ
diff --git a/audio/skill/xz_xunxun2.mp3 b/audio/skill/xz_xunxun2.mp3
index a374db5e1..737246af0 100644
Binary files a/audio/skill/xz_xunxun2.mp3 and b/audio/skill/xz_xunxun2.mp3 differ
diff --git a/audio/skill/yuanjiangfenghuotu1.mp3 b/audio/skill/yuanjiangfenghuotu1.mp3
new file mode 100644
index 000000000..167752250
Binary files /dev/null and b/audio/skill/yuanjiangfenghuotu1.mp3 differ
diff --git a/audio/skill/yuanjiangfenghuotu2.mp3 b/audio/skill/yuanjiangfenghuotu2.mp3
new file mode 100644
index 000000000..bf13a8f53
Binary files /dev/null and b/audio/skill/yuanjiangfenghuotu2.mp3 differ
diff --git a/audio/skill/yuanjiangfenghuotu3.mp3 b/audio/skill/yuanjiangfenghuotu3.mp3
new file mode 100644
index 000000000..6c35e10b7
Binary files /dev/null and b/audio/skill/yuanjiangfenghuotu3.mp3 differ
diff --git a/audio/skill/yuanjiangfenghuotu4.mp3 b/audio/skill/yuanjiangfenghuotu4.mp3
new file mode 100644
index 000000000..e654cc8be
Binary files /dev/null and b/audio/skill/yuanjiangfenghuotu4.mp3 differ
diff --git a/audio/skill/zhangwu1.mp3 b/audio/skill/zhangwu1.mp3
index b062da5a8..698b04329 100644
Binary files a/audio/skill/zhangwu1.mp3 and b/audio/skill/zhangwu1.mp3 differ
diff --git a/audio/skill/zhangwu2.mp3 b/audio/skill/zhangwu2.mp3
index e49c860a5..e4792998e 100644
Binary files a/audio/skill/zhangwu2.mp3 and b/audio/skill/zhangwu2.mp3 differ
diff --git a/audio/skill/zhaxiang_ol_sb_jiangwei1.mp3 b/audio/skill/zhaxiang_ol_sb_jiangwei1.mp3
new file mode 100644
index 000000000..950713bdf
Binary files /dev/null and b/audio/skill/zhaxiang_ol_sb_jiangwei1.mp3 differ
diff --git a/audio/skill/zhiheng_gz_jun_sunquan1.mp3 b/audio/skill/zhiheng_gz_jun_sunquan1.mp3
index bfe9aa2e5..1793a625d 100644
Binary files a/audio/skill/zhiheng_gz_jun_sunquan1.mp3 and b/audio/skill/zhiheng_gz_jun_sunquan1.mp3 differ
diff --git a/audio/skill/zhiheng_gz_jun_sunquan2.mp3 b/audio/skill/zhiheng_gz_jun_sunquan2.mp3
index aaf4b9cf2..d6cbabedf 100644
Binary files a/audio/skill/zhiheng_gz_jun_sunquan2.mp3 and b/audio/skill/zhiheng_gz_jun_sunquan2.mp3 differ
diff --git a/audio/skill/zhiman_guansuo2.mp3 b/audio/skill/zhiman_guansuo2.mp3
deleted file mode 100644
index ec7fbb654..000000000
Binary files a/audio/skill/zhiman_guansuo2.mp3 and /dev/null differ
diff --git a/card/guozhan.js b/card/guozhan.js
index 44f7cdc47..be87848e2 100644
--- a/card/guozhan.js
+++ b/card/guozhan.js
@@ -1831,7 +1831,9 @@ game.import("card", function () {
mod: {
maxHandcard: function (player, num) {
if (get.mode() == "guozhan") {
- if (player.hasSkill("huangjintianbingfu")) {
+ // if (player.hasSkill("hongfa")) {
+ // 村规
+ if (player.hasSkill("hongfa", null, null, false)) {
num += player.getExpansions("huangjintianbingfu").length;
}
return (
diff --git a/card/standard.js b/card/standard.js
index 1f121d6a7..5e55c0a57 100644
--- a/card/standard.js
+++ b/card/standard.js
@@ -608,6 +608,12 @@ game.import("card", function () {
if (target !== _status.event.dying) {
if (
!player.isPhaseUsing() ||
+ player.needsToDiscard(0, (i, player) => {
+ return (
+ !player.canIgnoreHandcard(i) &&
+ taos.includes(i)
+ );
+ }) ||
player.hasSkillTag(
"nokeep",
true,
@@ -619,7 +625,7 @@ game.import("card", function () {
)
)
return 2;
- let min = 7.2 - (4 * player.hp) / player.maxHp,
+ let min = 8.1 - (4.5 * player.hp) / player.maxHp,
nd = player.needsToDiscard(0, (i, player) => {
return (
!player.canIgnoreHandcard(i) &&
@@ -1407,7 +1413,7 @@ game.import("card", function () {
return 1;
},
basic: {
- order: 9,
+ order: 7.2,
useful: [5, 1],
value: 5,
},
@@ -1700,7 +1706,7 @@ game.import("card", function () {
return 1;
},
basic: {
- order: 9,
+ order: 7.2,
useful: 1,
value: 5,
},
@@ -1843,7 +1849,7 @@ game.import("card", function () {
}
},
basic: {
- order: 7.2,
+ order: 7,
useful: 4.5,
value: 9.2,
},
@@ -2111,12 +2117,13 @@ game.import("card", function () {
pos = get.position(button.link),
name = get.name(button.link);
if (pos == "j") {
- if (name == "lebu") {
+ let viewAs = button.link.viewAs;
+ if (viewAs == "lebu") {
let needs = target.needsToDiscard(2);
btv *= 1.08 + 0.2 * needs;
- } else if (name == "shandian" || name == "fulei" || name == "plague") btv /= 2;
+ } else if (viewAs == "shandian" || viewAs == "fulei") btv /= 2;
}
- if (get.attitude(player, get.owner(button.link)) > 0) btv = -btv;
+ if (att > 0) btv = -btv;
if (pos != "e") {
if (pos == "h" && !player.hasSkillTag("viewHandcard", null, target, true))
return btv + 0.1;
@@ -2156,6 +2163,7 @@ game.import("card", function () {
return get.value(card, target) > 0 && card != target.getEquip('jinhe');
}) && !js.some(card => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return true;
return get.effect(target, cardj, target, player) < 0;
})) return 0;
}
@@ -2164,6 +2172,7 @@ game.import("card", function () {
return get.value(card, target) <= 0;
}) || js.some(card => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return false;
return get.effect(target, cardj, target, player) < 0;
})) ? 1.5 : 0;
}
@@ -2180,6 +2189,7 @@ game.import("card", function () {
return get.value(card, target) > 0 && card != target.getEquip('jinhe');
}) || js.some(card => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return true;
return get.effect(target, cardj, target, player) < 0;
})) ? -1.5 : 1.5;
}
@@ -2187,6 +2197,7 @@ game.import("card", function () {
return get.value(card, target) <= 0;
}) || js.some(card => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return false;
return get.effect(target, cardj, target, player) < 0;
})) ? 1.5 : -1.5;
},
@@ -2218,6 +2229,7 @@ game.import("card", function () {
}) ||
js.some((card) => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return true;
return get.effect(target, cardj, target, player) < 0;
})
? -1.5
@@ -2228,6 +2240,7 @@ game.import("card", function () {
}) ||
js.some((card) => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return false;
return get.effect(target, cardj, target, player) < 0;
})
? 1.5
@@ -2250,6 +2263,7 @@ game.import("card", function () {
}) &&
!js.some((card) => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return true;
return get.effect(target, cardj, target, player) < 0;
})
)
@@ -2260,6 +2274,7 @@ game.import("card", function () {
}) ||
js.some((card) => {
var cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return false;
return get.effect(target, cardj, target, player) < 0;
})
? 1.5
@@ -2423,12 +2438,13 @@ game.import("card", function () {
pos = get.position(button.link),
name = get.name(button.link);
if (pos === "j") {
- if (name === "lebu") {
+ let viewAs = button.link.viewAs;
+ if (viewAs === "lebu") {
let needs = target.needsToDiscard(2);
val *= 1.08 + 0.2 * needs;
- } else if (name == "shandian" || name == "fulei" || name == "plague") val /= 2;
+ } else if (viewAs == "shandian" || viewAs == "fulei") val /= 2;
}
- if (get.attitude(player, get.owner(button.link)) > 0) val = -val;
+ if (att > 0) val = -val;
if (pos !== "e") return val;
let sub = get.subtypes(button.link);
if (sub.includes("equip1")) return (val * Math.min(3.6, target.hp)) / 3;
@@ -2466,6 +2482,7 @@ game.import("card", function () {
if (att > 0) {
if (js.some(card => {
const cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return false;
return get.effect(target, cardj, target, player) < 0;
})) return 3;
if (target.isDamaged() && es.some(card => card.name == 'baiyin') &&
@@ -2485,6 +2502,7 @@ game.import("card", function () {
}));
const noj = (js.length == 0 || !js.some(card => {
const cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return true;
return get.effect(target, cardj, target, player) < 0;
}))
if (noh && noe2 && noj) return 1.5;
@@ -2518,6 +2536,7 @@ game.import("card", function () {
if (
js.some((card) => {
const cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return false;
return get.effect(target, cardj, target, player) < 0;
})
)
@@ -2548,6 +2567,7 @@ game.import("card", function () {
js.length == 0 ||
!js.some((card) => {
const cardj = card.viewAs ? { name: card.viewAs } : card;
+ if (cardj.name == "xumou_jsrg") return true;
return get.effect(target, cardj, target, player) < 0;
});
if (noh && noe2 && noj) return 1.5;
diff --git a/card/yingbian.js b/card/yingbian.js
index d6b5e3bb5..52ea6f60f 100644
--- a/card/yingbian.js
+++ b/card/yingbian.js
@@ -61,7 +61,7 @@ game.import("card", function () {
var base = 0;
if (get.cardtag(card, "yingbian_all")) {
if (
- targets.filter(function (current) {
+ targets.some(function (current) {
var att = get.attitude(player, current);
if (att <= 0)
return (
@@ -74,7 +74,7 @@ game.import("card", function () {
return get.position(card) == "j" || get.value(card, current) <= 0;
}) > 1
);
- }).length
+ })
)
base += 6;
}
@@ -138,13 +138,11 @@ game.import("card", function () {
? -1.5
: 1.5;
var js = target.getCards("j");
- if (js.length) {
- var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0];
- if (js.length == 1 && get.effect(target, jj, target, player) >= 0) {
- return -1.5;
- }
- return 3;
- }
+ if (js.length && js.some(i => {
+ let cardj = i.viewAs ? { name: i.viewAs } : i;
+ if (cardj.name == "xumou_jsrg") return false;
+ return get.effect(target, cardj, target, player) < 0;
+ })) return 3;
return -1.5;
},
player: function (player, target) {
@@ -159,13 +157,11 @@ game.import("card", function () {
}
if (get.attitude(player, target) > 1) {
var js = target.getCards("j");
- if (js.length) {
- var jj = js[0].viewAs ? { name: js[0].viewAs } : js[0];
- if (js.length == 1 && get.effect(target, jj, target, player) >= 0) {
- return 0;
- }
- return 1;
- }
+ if (js.length && js.some(i => {
+ let cardj = i.viewAs ? { name: i.viewAs } : i;
+ if (cardj.name == "xumou_jsrg") return false;
+ return get.effect(target, cardj, target, player) < 0;
+ })) return 1;
return 0;
}
return 1;
diff --git a/character/clan/skill.js b/character/clan/skill.js
index 227297489..84e7cd145 100644
--- a/character/clan/skill.js
+++ b/character/clan/skill.js
@@ -1420,6 +1420,7 @@ const skills = {
delete event.result.skill;
},
ai: {
+ combo: "clanzhongliu",
order(item, player) {
player = player || _status.event.player;
var storage = _status.event.player.storage.clanjiexuan;
diff --git a/character/collab/character.js b/character/collab/character.js
index f677089f9..60b23bc80 100644
--- a/character/collab/character.js
+++ b/character/collab/character.js
@@ -20,6 +20,8 @@ const characters = {
old_lingju: ["female", "qun", 3, ["jieyuan", "fenxin_old"]],
sp_mushun: ["male", "qun", 4, ["moukui"]],
dc_wuyi: ["male", "shu", 4, ["dcbenxi"]],
+ quyuan: ["male", "qun", 3, ["dcqiusuo", "dclisao"]],
+ xin_sunquan: ["male", "wu", 3, ["dchuiwan", "dchuanli"]],
};
export default characters;
diff --git a/character/collab/intro.js b/character/collab/intro.js
index fd7369d05..5321c5b07 100644
--- a/character/collab/intro.js
+++ b/character/collab/intro.js
@@ -1,4 +1,5 @@
const characterIntro = {
+ quyuan: "屈原(约前340年~前278年),芈姓(一作嬭姓),屈氏,名平,字原,又自云名正则,字灵均,出生于楚国丹阳秭归(今湖北省宜昌市),战国时期楚国诗人、政治家。楚武王熊通之子屈瑕的后代(一说屈氏的来源是西周前期的楚国人屈紃)。屈原少年时受过良好的教育,博闻强识,志向远大。早年受楚怀王信任,任左徒、三闾大夫,兼管内政外交大事。提倡“美政”,主张对内举贤任能,修明法度,对外力主联齐抗秦。因遭贵族排挤诽谤,被先后流放至汉北和沅湘流域。前278年,楚国郢都被秦军攻破后,自沉于汨罗江,以身殉楚国。屈原是中国历史上一位伟大的爱国诗人,中国浪漫主义文学的奠基人,“楚辞”的创立者和代表作家,开辟了“香草美人”的传统,被誉为“楚辞之祖”,楚国有名的辞赋家宋玉、唐勒、景差都受到屈原的影响。屈原作品的出现,标志着中国诗歌进入了一个由大雅歌唱到浪漫独创的新时代,其主要作品有《离骚》《九歌》《九章》《天问》等。以屈原作品为主体的《楚辞》是中国浪漫主义文学的源头之一,对后世诗歌产生了深远影响。成为中国文学史上的璀璨明珠,“逸响伟辞,卓绝一世”。“路漫漫其修远兮,吾将上下而求索”,屈原的“求索”精神,成为后世仁人志士所信奉和追求的一种高尚精神。",
sunwukong: "孙悟空是中国古典小说《西游记》的主人公,也是中国神话中的民俗神祇之一,明代百回本《西游记》书中最为深入人心的形象之一。《西游记》中的孙悟空本是天地生成的一个石猴,率领群猴在花果山水帘洞过着逍遥自在的日子,后来为学习长生的法术而拜菩提祖师为师,学会了七十二变和筋斗云等绝技。后来他前往东海龙宫夺取如意金箍棒,又大闹地府勾了生死簿,惊动天庭,天庭两次派兵征讨花果山,仍然降他不得,只好请西天如来佛祖前来助阵。如来佛祖以五行山将悟空压在山下五百年。五百年后,悟空在观音菩萨的指点下拜唐僧为师,并跟随唐僧前往西天求取真经。路上唐僧又收了猪八戒、沙和尚两个徒弟,众人在途中斩妖除魔、历经磨难,终于取得真经,修成正果。",
longwang: "东海龙王,名敖广,是中国古代神话传说中的龙族之王,为“四海龙王”之首,亦为所有水族之王。统治东海之洋,主宰着雨水、雷鸣、洪灾、海潮、海啸等。曾下陷东京、水淹陈塘关(影视设定)。在中国以东方为尊位,按周易来说东为阳,故此东海龙王排第一便是理所应当。常记载于《西游记》《封神演义》《三教搜神大全》等文学典籍。东海龙王居于东海的海底水晶宫(花果山瀑布顺流可直抵龙宫)。虽为司雨之神,但其保持着较大的特殊自由性,人间降雨由其它江河湖井龙王完成,很少需要东海龙王亲自降雨。海洋管辖之权为龙王所有,天庭一般任其自治。",
taoshen: "涛神,是司掌钱塘江的神,传说其原型为春秋战国时期的吴国大臣伍子胥。伍子胥从楚国投奔吴国,为吴国立下了汗马功劳;但吴王夫差听信太宰伯嚭的谗言,逐渐疏远了伍子胥,最后还赐死了他。伍子胥含冤身亡,十分悲愤,做出了吴国灭亡的预言后自杀。暴怒的夫差下令用皮革包裹住伍子胥的尸身,在五月五日这天丢进钱塘江。百姓可怜伍子胥忠于吴王却遭受惨死,因此将五月五日这一天定为节日,以此纪念伍子胥,这也是端午节的来历之一。",
diff --git a/character/collab/skill.js b/character/collab/skill.js
index 2a8cf5050..14d974ae0 100644
--- a/character/collab/skill.js
+++ b/character/collab/skill.js
@@ -2,6 +2,361 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
+ //会玩孙权
+ dchuiwan: {
+ audio: 2,
+ trigger: { player: "drawBegin" },
+ filter(event, player) {
+ return lib.inpile.some(name => {
+ const type = get.type(name);
+ if (type != "basic" && type != "trick") return false;
+ return !player.getStorage("dchuiwan_used").includes(name);
+ });
+ },
+ async cost(event, trigger, player) {
+ let result = await player
+ .chooseButton(
+ [
+ get.prompt2("dchuiwan"),
+ [
+ lib.inpile.filter(name => {
+ const type = get.type(name);
+ if (type != "basic" && type != "trick") return false;
+ return !player.getStorage("dchuiwan_used").includes(name);
+ }),
+ "vcard",
+ ],
+ ],
+ [1, trigger.num]
+ )
+ .set("ai", button => {
+ if (!get.cardPile2(button.link[2])) return 0;
+ return get.value({ name: button.link[2] }, get.event("player"));
+ })
+ .forResult();
+ if (result.bool) {
+ result.cost_data = result.links;
+ }
+ event.result = result;
+ },
+ async content(event, trigger, player) {
+ trigger.cancel();
+ if (!player.storage.dchuiwan_used) {
+ player.when({ global: "phaseAfter" }).then(() => delete player.storage.dchuiwan_used);
+ }
+ player.markAuto(
+ "dchuiwan_used",
+ event.cost_data.map(name => name[2])
+ );
+ let list = [];
+ for (const name of event.cost_data) {
+ const card = get.cardPile2(name[2]);
+ if (card) list.push(card);
+ }
+ if (list.length) await player.gain(list, "gain2");
+ else player.chat("无牌可得?!");
+ },
+ },
+ dchuanli: {
+ audio: 2,
+ trigger: { player: "phaseJieshuBegin" },
+ filter(event, player) {
+ return (
+ player.getHistory("useCard", evt => {
+ return (evt.targets || []).includes(player);
+ }).length >= 3 ||
+ game.hasPlayer(target => {
+ if (target == player) return false;
+ return (
+ player.getHistory("useCard", evt => {
+ return (evt.targets || []).includes(target);
+ }).length >= 3
+ );
+ })
+ );
+ },
+ direct: true,
+ async content(event, trigger, player) {
+ let zhangzhang = false,
+ zhouyu = false;
+ if (
+ player.getHistory("useCard", evt => {
+ return (evt.targets || []).includes(player);
+ }).length >= 3
+ ) {
+ const result = await player
+ .chooseTarget(get.prompt("dchuanli"), "令一名其他角色的所有技能失效,然后令其获得〖直谏〗和〖固政〗直到其回合结束", (card, player, target) => {
+ return target != player && !target.hasSkill("dchuanli_zhangzhang");
+ })
+ .set("ai", target => {
+ const player = get.event("player");
+ return (
+ get.rank("zhangzhang", true) -
+ ["name", "name1", "name2"].reduce((sum, name) => {
+ if (!target[name] || !lib.character[target[name]] || (name == "name1" && target.name1 == target.name)) return sum;
+ return sum + get.rank(target[name], true);
+ }, 0)
+ );
+ })
+ .forResult();
+ if (result.bool) {
+ zhangzhang = true;
+ const target = result.targets[0];
+ await player.logSkill("dchuanli", target);
+ target.addTempSkill("dchuanli_zhangzhang", { player: "phaseAfter" });
+ target.markSkillCharacter("dchuanli_zhangzhang", "zhangzhang", "唤理-内事", "内事不决问张昭");
+ await target.addAdditionalSkills("dchuanli_zhangzhang", ["zhijian", "guzheng"]);
+ }
+ }
+ const targets = game.filterPlayer(target => {
+ if (target == player || target.hasSkill("dchuanli_zhouyu")) return false;
+ return (
+ player.getHistory("useCard", evt => {
+ return (evt.targets || []).includes(target);
+ }).length >= 3
+ );
+ });
+ if (targets.length) {
+ const result = await player
+ .chooseTarget(get.prompt("dchuanli"), "令一名其他角色的所有技能失效,然后令其获得〖英姿〗和〖反间〗直到其回合结束", (card, player, target) => {
+ return get.event("targets").includes(target);
+ })
+ .set("ai", target => {
+ const player = get.event("player");
+ return (
+ get.rank("re_zhouyu", true) -
+ ["name", "name1", "name2"].reduce((sum, name) => {
+ if (!target[name] || !lib.character[target[name]] || (name == "name1" && target.name1 == target.name)) return sum;
+ return sum + get.rank(target[name], true);
+ }, 0)
+ );
+ })
+ .set("targets", targets)
+ .forResult();
+ if (result.bool) {
+ zhouyu = true;
+ const target = result.targets[0];
+ await player.logSkill("dchuanli", target);
+ target.addTempSkill("dchuanli_zhouyu", { player: "phaseAfter" });
+ target.markSkillCharacter("dchuanli_zhouyu", "re_zhouyu", "唤理-外事", "外事不决问周瑜");
+ await target.addAdditionalSkills("dchuanli_zhouyu", ["reyingzi", "refanjian"]);
+ }
+ }
+ if (zhangzhang && zhouyu) {
+ await player.logSkill("dchuanli");
+ if (player.storage.dchuanli_sunquan) delete player.storage.dchuanli_sunquan;
+ await player.addAdditionalSkills("dchuanli_sunquan", "rezhiheng");
+ player.addSkill("dchuanli_sunquan");
+ }
+ },
+ subSkill: {
+ zhangzhang: {
+ init(player, skill) {
+ player.addSkillBlocker(skill);
+ },
+ onremove(player, skill) {
+ player.removeSkillBlocker(skill);
+ player.removeAdditionalSkills(skill);
+ },
+ charlotte: true,
+ skillBlocker(skill) {
+ return !["zhijian", "guzheng"].includes(skill) && skill != "dchuanli_zhangzhang" && !lib.skill[skill].charlotte;
+ },
+ },
+ zhouyu: {
+ init(player, skill) {
+ player.addSkillBlocker(skill);
+ },
+ onremove(player, skill) {
+ player.removeSkillBlocker(skill);
+ player.removeAdditionalSkills(skill);
+ },
+ charlotte: true,
+ skillBlocker(skill) {
+ return !["reyingzi", "refanjian"].includes(skill) && skill != "dchuanli_zhouyu" && !lib.skill[skill].charlotte;
+ },
+ },
+ sunquan: {
+ charlotte: true,
+ onremove(player, skill) {
+ delete player.storage[skill];
+ },
+ trigger: { player: "phaseAfter" },
+ forced: true,
+ popup: false,
+ async content(event, trigger, player) {
+ if (!player.storage.dchuanli_sunquan) {
+ player.storage.dchuanli_sunquan = true;
+ } else {
+ await player.removeAdditionalSkills("dchuanli_sunquan");
+ player.removeSkill("dchuanli_sunquan");
+ }
+ },
+ },
+ },
+ derivation: ["zhijian", "guzheng", "reyingzi", "refanjian", "rezhiheng"],
+ },
+ //屈原
+ dcqiusuo: {
+ audio: 2,
+ trigger: { source: "damageSource" },
+ frequent: true,
+ async content(event, trigger, player) {
+ const tiesuo = get.cardPile("tiesuo");
+ if (tiesuo) await player.gain(tiesuo, "gain2");
+ },
+ },
+ dclisao: {
+ audio: 2,
+ enable: "phaseUse",
+ filterTarget: true,
+ selectTarget: [1, 2],
+ usable: 1,
+ multitarget: true,
+ multiline: true,
+ async content(event, trigger, player) {
+ let targets = event.targets.sortBySeat();
+ //处理问题
+ let answer = [],
+ gaifa = targets.slice(); //该罚
+ let question = [];
+ const sentences = _status.lisao_text.randomGets(2).randomSort();
+ const goon = Math.round(Math.random());
+ question.addArray(["请回答《离骚》中“" + sentences[0].split(",")[goon] + "”的" + (goon ? "上" : "下") + "句", [sentences[0].split(",")[1 - goon], sentences[1].split(",")[1 - goon]].randomSort()]);
+ //人类和AI
+ //AI随机排序一下,模拟不同顺序回答
+ let humans = targets.filter(current => current === game.me || current.isOnline());
+ let locals = targets.slice(0).randomSort();
+ locals.removeArray(humans);
+ const eventId = get.id();
+ const send = (question, current, eventId) => {
+ lib.skill.dclisao.chooseControl(question, current, eventId);
+ game.resume();
+ };
+ //让读条不消失并显示读条
+ event._global_waiting = true;
+ let time = 10000;
+ if (lib.configOL && lib.configOL.choose_timeout) time = parseInt(lib.configOL.choose_timeout) * 1000;
+ targets.forEach(current => current.showTimer(time));
+ //先处理人类玩家
+ if (humans.length > 0) {
+ const solve = function (resolve, reject) {
+ return function (result, player) {
+ if (result && result.control) {
+ resolve();
+ answer.push([player, result.control]);
+ } else reject();
+ };
+ };
+ await Promise.any(
+ humans.map(current => {
+ return new Promise(async (resolve, reject) => {
+ if (current.isOnline()) {
+ current.send(send, question, current, eventId);
+ current.wait(solve(resolve, reject));
+ } else {
+ const next = lib.skill.dclisao.chooseControl(question, current, eventId);
+ const solver = solve(resolve, reject);
+ if (_status.connectMode) game.me.wait(solver);
+ const result = await next.forResult();
+ if (_status.connectMode) game.me.unwait(result, current);
+ else solver(result, current);
+ }
+ });
+ })
+ ).catch(() => {});
+ game.broadcastAll("cancel", eventId);
+ }
+ //再处理单机的他人控制玩家/AI玩家
+ if (locals.length > 0) {
+ for (let current of locals) {
+ const result = await lib.skill.dclisao.chooseControl(question, current).forResult();
+ if (result && result.control) {
+ answer.push([current, result.control]);
+ }
+ }
+ }
+ //清除读条
+ delete event._global_waiting;
+ for (let i of targets) i.hideTimer();
+ //处理结果
+ if (answer.length) {
+ let show = false;
+ for (const list of answer) {
+ list[0].chat(list[1]);
+ game.log(list[0], "的答案为", "#y" + list[1]);
+ if (list[1] == sentences[0].split(",")[1 - goon]) {
+ list[0].popup("回答正确", "wood");
+ game.log(list[0], "回答正确");
+ if (!show) {
+ show = true;
+ if (list[0].countCards("h")) {
+ await list[0].showHandcards();
+ }
+ }
+ gaifa.remove(list[0]);
+ } else {
+ list[0].popup("回答错误", "fire");
+ game.log(list[0], "回答错误");
+ }
+ }
+ await game.asyncDelay();
+ }
+ if (gaifa.length) {
+ for (const i of gaifa) {
+ i.addTempSkill("dclisao_gaifa");
+ }
+ }
+ },
+ chooseControl(question, current, eventId) {
+ const next = current.chooseControl(question[1]);
+ next.set("prompt", question[0]);
+ next.set("id", eventId);
+ next.set("_global_waiting", true);
+ next.set("ai", () => Math.round(Math.random()));
+ return next;
+ },
+ init() {
+ //《离骚》(高中节选)
+ if (!_status.lisao_text) {
+ let text = "长太息以掩涕兮,哀民生之多艰。余虽好修姱以鞿羁兮,謇朝谇而夕替。既替余以蕙纕兮,又申之以揽茝。亦余心之所善兮,虽九死其犹未悔。怨灵修之浩荡兮,终不察夫民心。众女嫉余之蛾眉兮,谣诼谓余以善淫。固时俗之工巧兮,偭规矩而改错。背绳墨以追曲兮,竞周容以为度。忳郁邑余侘傺兮,吾独穷困乎此时也。宁溘死以流亡兮,余不忍为此态也。鸷鸟之不群兮,自前世而固然。何方圜之能周兮,夫孰异道而相安。屈心而抑志兮,忍尤而攘诟。伏清白以死直兮,固前圣之所厚。悔相道之不察兮,延伫乎吾将反。回朕车以复路兮,及行迷之未远。步余马于兰皋兮,驰椒丘且焉止息。进不入以离尤兮,退将复修吾初服。制芰荷以为衣兮,集芙蓉以为裳。不吾知其亦已兮,苟余情其信芳。高余冠之岌岌兮,长余佩之陆离。芳与泽其杂糅兮,唯昭质其犹未亏。忽反顾以游目兮,将往观乎四荒。佩缤纷其繁饰兮,芳菲菲其弥章。民生各有所乐兮,余独好修以为常。虽体解吾犹未变兮,岂余心之可惩。";
+ _status.lisao_text = text.slice(0, -1).split("。");
+ }
+ },
+ ai: {
+ order: 10,
+ result: {
+ target(player, target) {
+ if (target.hasSkill("dclisao_gaifa")) return 0;
+ if (get.damageEffect(target, player, player) < 0 && get.attitude(player, target) > 0) return 0;
+ let cards = player.getCards("hs", card => get.tag(card, "damage") && player.canUse(card, target) && get.effect(target, card, player, player) > 0);
+ if (!cards.length) return 0;
+ let cardx = cards.filter(card => get.name(card) == "sha");
+ cardx.sort((a, b) => get.effect(target, b, player, player) - get.effect(target, a, player, player));
+ cardx = cardx.slice(Math.min(cardx.length, player.getCardUsable("sha")), cardx.length);
+ cards.removeArray(cardx);
+ return -cards.reduce((sum, card) => sum + get.effect(target, card, player, player), 0) - 10;
+ },
+ },
+ },
+ subSkill: {
+ gaifa: {
+ charlotte: true,
+ trigger: { player: "damageBegin3" },
+ filter(event, player) {
+ return player.getHistory("damage", evt => evt.num > 0).length;
+ },
+ forced: true,
+ popup: false,
+ async content(event, trigger, player) {
+ trigger.num = player.getHistory("damage", evt => evt.num > 0).lastItem.num * 2;
+ },
+ mark: true,
+ marktext: "江",
+ intro: { content: "不能熟记《离骚》的惩罚——本回合受到伤害时,若你本回合已受到过伤害,则此伤害值改为上一次受到的伤害的两倍" },
+ },
+ },
+ },
//名将吴懿
dcbenxi: {
trigger: {
@@ -20,15 +375,16 @@ const skills = {
const map = lib.skill.dcbenxi.getMap(),
list = Object.keys(map);
if (list.length > 0) {
- const skill = list.randomGet(), voiceMap = game.parseSkillTextMap(skill, map[skill]);
+ const skill = list.randomGet(),
+ voiceMap = game.parseSkillTextMap(skill, map[skill]);
player.storage.dcbenxi_pending = skill;
findaudio: for (let data of voiceMap) {
- if(!data.text) continue;
+ if (!data.text) continue;
const pinyins = get.pinyin(data.text, false);
for (let i = 0; i < pinyins.length - 1; i++) {
if (pinyins[i] === "wu" && pinyins[i + 1] === "yi") {
player.chat(data.text);
- game.broadcastAll(file => game.playAudio(file), data.file)
+ game.broadcastAll(file => game.playAudio(file), data.file);
break findaudio;
}
}
@@ -37,36 +393,34 @@ const skills = {
} else {
const skill = player.storage.dcbenxi_pending;
if (skill) {
- if (player.hasSkill(skill, null, false)){
+ if (player.hasSkill(skill, null, false)) {
const targets = game.filterPlayer(current => current != player).sortBySeat();
- player.line(targets, 'fire');
- for(let target of targets){
- if(target.isIn()) await target.damage();
+ player.line(targets, "fire");
+ for (let target of targets) {
+ if (target.isIn()) await target.damage();
}
- }
- else{
- await player.addTempSkills([skill], {player: "phaseBegin"});
+ } else {
+ await player.addTempSkills([skill], { player: "phaseBegin" });
}
delete player.storage.dcbenxi_pending;
}
}
},
- onremove(player){
+ onremove(player) {
delete player.storage.dcbenxi;
delete player.storage.dcbenxi_pending;
},
mark: true,
marktext: "☯",
intro: {
- mark(dialog, storage, player){
- if(storage){
+ mark(dialog, storage, player) {
+ if (storage) {
const skill = player.storage.dcbenxi_pending;
- if(skill){
+ if (skill) {
dialog.addText(`锁定技,当你下次失去手牌后,你获得技能〖${get.translation(skill)}〗直到你的下回合开始。若已获得该技能,则改为对所有其他角色各造成1点伤害。`, false);
dialog.add('
【' + get.translation(lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2)) + "】
" + get.skillInfoTranslation(skill, player) + "
");
}
- }
- else{
+ } else {
return "锁定技。当你下次失去手牌后,你随机念出一句拼音中含有“wu,yi”的台词。";
}
},
@@ -453,13 +807,11 @@ const skills = {
trigger: {
player: "damageEnd",
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
if (get.itemtype(trigger.cards) == "cards" && get.position(trigger.cards[0], true) == "o") {
- player.gain(trigger.cards, "gain2");
+ await player.gain(trigger.cards, "gain2");
}
- player.draw(player.countMark("dcjianxiong") + 1, "nodelay");
- "step 1";
+ await player.draw(player.countMark("dcjianxiong") + 1, "nodelay");
if (player.countMark("dcjianxiong") < 4) player.addMark("dcjianxiong", 1, false);
},
marktext: "雄",
@@ -509,12 +861,10 @@ const skills = {
if (player.getStorage("dcrende_targeted").includes(target)) return false;
return player != target && target.countGainableCards(player, "h") > 1;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
player.addTempSkill("dcrende_targeted", "phaseUseAfter");
- player.markAuto("dcrende_targeted", [target]);
- player.gainPlayerCard(target, "h", true, 2);
- "step 1";
+ player.markAuto("dcrende_targeted", [event.target]);
+ await player.gainPlayerCard(event.target, "h", true, 2);
var list = [];
for (var name of lib.inpile) {
if (get.type(name) != "basic") continue;
@@ -542,45 +892,45 @@ const skills = {
}
}
if (list.length) {
- player.chooseButton(["是否视为使用一张基本牌?", [list, "vcard"]]).set("ai", function (button) {
- var player = _status.event.player;
- var card = {
- name: button.link[2],
- nature: button.link[3],
- isCard: true,
- };
- if (card.name == "tao") {
- if (player.hp == 1 || (player.hp == 2 && !player.hasShan()) || player.needsToDiscard()) return 5;
- return 1;
- }
- if (card.name == "sha") {
- if (
- game.hasPlayer(function (current) {
- return player.canUse(card, current) && get.effect(current, card, player, player) > 0;
- })
- ) {
- if (card.nature == "fire") return 2.95;
- if (card.nature == "thunder" || card.nature == "ice") return 2.92;
- return 2.9;
+ const result = await player
+ .chooseButton(["是否视为使用一张基本牌?", [list, "vcard"]])
+ .set("ai", function (button) {
+ var player = _status.event.player;
+ var card = {
+ name: button.link[2],
+ nature: button.link[3],
+ isCard: true,
+ };
+ if (card.name == "tao") {
+ if (player.hp == 1 || (player.hp == 2 && !player.hasShan()) || player.needsToDiscard()) return 5;
+ return 1;
+ }
+ if (card.name == "sha") {
+ if (
+ game.hasPlayer(function (current) {
+ return player.canUse(card, current) && get.effect(current, card, player, player) > 0;
+ })
+ ) {
+ if (card.nature == "fire") return 2.95;
+ if (card.nature == "thunder" || card.nature == "ice") return 2.92;
+ return 2.9;
+ }
+ return 0;
+ }
+ if (card.name == "jiu") {
+ return 0.5;
}
return 0;
- }
- if (card.name == "jiu") {
- return 0.5;
- }
- return 0;
- });
- } else {
- event.finish();
- }
- "step 2";
- if (result && result.bool && result.links[0]) {
- var card = {
- name: result.links[0][2],
- nature: result.links[0][3],
- isCard: true,
- };
- player.chooseUseTarget(card, true);
+ })
+ .forResult();
+ if (result && result.bool && result.links[0]) {
+ var card = {
+ name: result.links[0][2],
+ nature: result.links[0][3],
+ isCard: true,
+ };
+ await player.chooseUseTarget(card, true);
+ }
}
},
subSkill: {
@@ -635,24 +985,24 @@ const skills = {
return 6 - get.value(card);
},
group: "dczhiheng_add",
- content() {
- "step 0";
- player.discard(cards);
- event.num = 1;
+ async content(event, trigger, player) {
+ let num = 1;
var hs = player.getCards("h");
- if (!hs.length) event.num = 0;
- for (var i = 0; i < hs.length; i++) {
- if (!cards.includes(hs[i])) {
- event.num = 0;
- break;
+ if (!hs.length) num = 0;
+ else {
+ for (var i = 0; i < hs.length; i++) {
+ if (!event.cards.includes(hs[i])) {
+ num = 0;
+ break;
+ }
}
}
- "step 1";
- player.draw(event.num + cards.length);
+ await player.discard(event.cards);
+ await player.draw(num + event.cards.length);
},
subSkill: {
add: {
- audio: 2,
+ audio: "rezhiheng",
trigger: {
source: "damageSource",
},
@@ -715,8 +1065,7 @@ const skills = {
audio: 2,
enable: "phaseUse",
usable: 1,
- content() {
- "step 0";
+ async content(event, trigger, player) {
var list = [];
for (var i in lib.skill.dcbianzhuang.characterMap) {
if (lib.character[i] && get.is.object(lib.skill[lib.skill.dcbianzhuang.characterMap[i]])) list.push(i);
@@ -727,10 +1076,12 @@ const skills = {
return;
}
var skills = characters.map(i => lib.skill.dcbianzhuang.characterMap[i]);
- player.chooseControl(skills).set("dialog", ["选择获得一个技能并“变装”", [characters, "character"]]);
- "step 1";
+ const result = await player
+ .chooseControl(skills)
+ .set("dialog", ["选择获得一个技能并“变装”", [characters, "character"]])
+ .forResult();
var skill = result.control;
- player.addTempSkills(skill, "dcbianzhuangAfter");
+ await player.addTempSkills(skill, "dcbianzhuangAfter");
for (var i in lib.skill.dcbianzhuang.characterMap) {
if (lib.skill.dcbianzhuang.characterMap[i] == skill) {
player.flashAvatar("dcbianzhuang", i);
@@ -739,13 +1090,12 @@ const skills = {
break;
}
}
- player.chooseUseTarget("sha", true, false, "nodistance");
- "step 2";
- if (result.bool && !player.storage.dcbianzhuang_inited) {
+ const result2 = await player.chooseUseTarget("sha", true, false, "nodistance").forResult();
+ if (result2.bool && !player.storage.dcbianzhuang_inited) {
player.addMark("dcbianzhuang", 1, false);
if (player.countMark("dcbianzhuang") > 2) {
player.storage.dcbianzhuang_inited = true;
- player.reinitCharacter(get.character(player.name2, 3).includes("dcbianzhuang") ? player.name2 : player.name1, "wu_zhutiexiong");
+ await player.reinitCharacter(get.character(player.name2, 3).includes("dcbianzhuang") ? player.name2 : player.name1, "wu_zhutiexiong");
}
}
},
@@ -803,9 +1153,8 @@ const skills = {
filter(event, player) {
return player.countCards("h") > 0;
},
- content() {
- "step 0";
- player
+ async content(event, trigger, player) {
+ const result = await player
.chooseCard("h", get.prompt("dctongliao"), "选择一张牌标记为“通辽”", function (card, player) {
if (card.hasGaintag("dctongliao")) return false;
var num = get.number(card, player);
@@ -816,12 +1165,12 @@ const skills = {
.set("ai", function (card) {
var player = _status.event.player;
return 1 + Math.max(0, player.getUseValue(card, null, true));
- });
- "step 1";
+ })
+ .forResult();
if (result.bool) {
- player.logSkill("dctongliao");
+ await player.logSkill("dctongliao");
player.addGaintag(result.cards, "dctongliao");
- game.delayx();
+ await game.asyncDelayx();
}
},
mod: {
@@ -925,10 +1274,9 @@ const skills = {
audio: 2,
trigger: { player: "phaseJudgeBefore" },
direct: true,
- content() {
- "step 0";
+ async content(event, trigger, player) {
var check = player.countCards("h") > 2;
- player
+ const result = await player
.chooseTarget(get.prompt("clbjisu"), "跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】", function (card, player, target) {
if (player == target) return false;
return player.canUse({ name: "sha" }, target, false);
@@ -938,10 +1286,10 @@ const skills = {
if (!_status.event.check) return 0;
return get.effect(target, { name: "sha" }, _status.event.player);
})
- .setHiddenSkill("clbjisu");
- "step 1";
+ .setHiddenSkill("clbjisu")
+ .forResult();
if (result.bool) {
- player.useCard({ name: "sha", isCard: true }, result.targets[0], false, "clbjisu");
+ await player.useCard({ name: "sha", isCard: true }, result.targets[0], false, "clbjisu");
trigger.cancel();
player.skip("phaseDraw");
}
@@ -1085,9 +1433,7 @@ const skills = {
direct: true,
priority: 11 + 45 + 14 + 19 + 19 + 810,
content() {
- "step 0";
player.removeGaintag("dcshixian_yayun");
- "step 1";
player.addGaintag(
player.getCards("h", card => {
return get.is.yayun(get.translation(card.name), get.translation(trigger.card.name));
@@ -1110,15 +1456,13 @@ const skills = {
check(event, player) {
return get.attitude(player, event.source) >= 0 || player.hp <= Math.max(2, event.num);
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
trigger.cancel();
- "step 1";
var card = get.cardPile2(function (card) {
return get.type(card, null, false) == "equip";
}),
source = trigger.source;
- if (card && source && source.isIn()) source.gain(card, "gain2");
+ if (card && source && source.isIn()) await source.gain(card, "gain2");
},
ai: {
filterDamage: true,
@@ -1152,13 +1496,14 @@ const skills = {
complexCard: true,
prompt: "弃置两张颜色不同的牌并改变天气",
check: card => 4.5 - get.value(card),
- content() {
- "step 0";
+ async content(event, trigger, player) {
var list = ["烈日", "雷电", "大浪", "暴雨", "大雾"].randomGets(2);
- player.chooseButton(true, ["请选择执行一个天气", [list.map(i => [i, '"]), "textbutton"]]).set("ai", function (button) {
- return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player);
- });
- "step 1";
+ const result = await player
+ .chooseButton(true, ["请选择执行一个天气", [list.map(i => [i, '"]), "textbutton"]])
+ .set("ai", function (button) {
+ return lib.skill.dcsitian.weathers[button.link].ai(_status.event.player);
+ })
+ .forResult();
if (result.bool) {
var choice = result.links[0];
game.log(player, "将当前天气变更为", "#g" + choice);
@@ -1225,47 +1570,36 @@ const skills = {
},
雷电: {
description: "你令其他角色各进行一次判定。若结果为♠2~9,则其受到3点无来源雷属性伤害。",
- content() {
- "step 0";
+ async content(event, trigger, player) {
var targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, "thunder");
- event.targets = targets;
- "step 1";
- var target = targets.shift();
- if (!target.isIn()) {
- if (targets.length > 0) event.redo();
- else {
- event.finish();
- return;
- }
- }
- event.target = target;
- event.judgestr = get.translation("shandian");
- target.judge(lib.card.shandian.judge, event.judgestr).judge2 = lib.card.shandian.judge2;
- //game.delayx(1.5);
- "step 2";
- var name = "shandian";
- if (event.cancelled && !event.direct) {
- if (lib.card[name].cancel) {
- var next = game.createEvent(name + "Cancel");
- next.setContent(lib.card[name].cancel);
+ for (const target of targets) {
+ if (!target.isIn()) continue;
+ const result = await target.judge(lib.card.shandian.judge, get.translation("shandian")).set("judge2", lib.card.shandian.judge2).forResult();
+ var name = "shandian";
+ if (event.cancelled && !event.direct) {
+ if (lib.card[name].cancel) {
+ var next = game.createEvent(name + "Cancel");
+ next.setContent(lib.card[name].cancel);
+ next.cards = [];
+ next.card = get.autoViewAs({ name: name });
+ next.player = target;
+ await next;
+ }
+ } else {
+ var next = game.createEvent(name);
+ next.setContent(function () {
+ if (result.bool == false) {
+ player.damage(3, "thunder", "nosource");
+ }
+ });
+ next._result = result;
next.cards = [];
next.card = get.autoViewAs({ name: name });
next.player = target;
+ await next;
}
- } else {
- var next = game.createEvent(name);
- next.setContent(function () {
- if (result.bool == false) {
- player.damage(3, "thunder", "nosource");
- }
- });
- next._result = result;
- next.cards = [];
- next.card = get.autoViewAs({ name: name });
- next.player = target;
}
- if (targets.length > 0) event.goto(1);
},
ai(player) {
var effect = 0;
@@ -1278,23 +1612,20 @@ const skills = {
},
大浪: {
description: "你弃置其他角色装备区内的所有牌(装备区内没有牌的角色改为失去1点体力)。",
- content() {
- "step 0";
+ async content(event, trigger, player) {
var targets = game.filterPlayer(current => current != player).sortBySeat();
player.line(targets, "green");
- event.targets = targets;
- "step 1";
- var target = targets.shift();
- if (target.isIn()) {
- var num = target.countCards("e");
- if (num > 0) {
- player.discardPlayerCard(target, true, "e", num);
- } else {
- target.loseHp();
- game.delayex();
+ for (const target of targets) {
+ if (target.isIn()) {
+ var num = target.countCards("e");
+ if (num > 0) {
+ await player.discardPlayerCard(target, true, "e", num);
+ } else {
+ await target.loseHp();
+ await game.asyncDelayx();
+ }
}
}
- if (targets.length > 0) event.redo();
},
ai(player) {
var effect = 0;
@@ -1312,19 +1643,20 @@ const skills = {
},
暴雨: {
description: "你弃置一名角色的所有手牌。若其没有手牌,则改为令其失去1点体力。",
- content() {
- "step 0";
- player.chooseTarget("请选择【暴雨】的目标", "令目标角色弃置所有手牌。若其没有手牌,则其改为失去1点体力。").set("ai", function (current) {
- var es = current.getCards("h"),
- player = _status.event.player;
- if (es.length > 0) {
- var att = get.attitude(player, current),
- val = get.value(es, current);
- return -Math.sqrt(att) * val;
- }
- return get.effect(current, { name: "losehp" }, player, player);
- });
- "step 1";
+ async content(event, trigger, player) {
+ const result = await player
+ .chooseTarget("请选择【暴雨】的目标", "令目标角色弃置所有手牌。若其没有手牌,则其改为失去1点体力。")
+ .set("ai", function (current) {
+ var es = current.getCards("h"),
+ player = _status.event.player;
+ if (es.length > 0) {
+ var att = get.attitude(player, current),
+ val = get.value(es, current);
+ return -Math.sqrt(att) * val;
+ }
+ return get.effect(current, { name: "losehp" }, player, player);
+ })
+ .forResult();
if (result.bool) {
var target = result.targets[0];
player.line(target, "green");
@@ -1591,11 +1923,10 @@ const skills = {
}
return false;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
var num = player.storage.ruyijingubang_skill;
if (num == 4) {
- player
+ const result = await player
.chooseTarget(get.prompt("ruyijingubang_effect"), "为" + get.translation(trigger.card) + "额外指定一个目标", function (card, player, target) {
return !_status.event.sourcex.includes(target) && player.canUse(_status.event.card, target, false);
})
@@ -1604,9 +1935,15 @@ const skills = {
var player = _status.event.player;
return get.effect(target, _status.event.card, player, player);
})
- .set("card", trigger.card);
+ .set("card", trigger.card)
+ .forResult();
+ if (result.bool) {
+ if (!event.isMine() && !event.isOnline()) await game.asyncDelayx();
+ await player.logSkill("ruyijingubang_effect", result.targets);
+ trigger.targets.addArray(result.targets);
+ }
} else {
- player.logSkill("ruyijingubang_effect");
+ await player.logSkill("ruyijingubang_effect");
if (num == 2) {
trigger.baseDamage++;
game.log(trigger.card, "的伤害+1");
@@ -1614,18 +1951,8 @@ const skills = {
trigger.directHit.addArray(game.filterPlayer());
game.log(trigger.card, "不可被响应");
}
- event.finish();
+ return;
}
- "step 1";
- if (result.bool) {
- if (!event.isMine() && !event.isOnline()) game.delayx();
- event.targets = result.targets;
- } else {
- event.finish();
- }
- "step 2";
- player.logSkill("ruyijingubang_effect", event.targets);
- trigger.targets.addArray(event.targets);
},
},
//涛神
@@ -1724,13 +2051,11 @@ const skills = {
spduyi: {
enable: "phaseUse",
usable: 1,
- content() {
- "step 0";
- event.card = get.cards()[0];
- game.cardsGotoOrdering(event.card);
- player.showCards(event.card);
- "step 1";
- player
+ async content(event, trigger, player) {
+ const card = get.cards()[0];
+ await game.cardsGotoOrdering(card);
+ await player.showCards(card);
+ const result = await player
.chooseTarget("令一名角色获得" + get.translation(card), true)
.set("ai", function (target) {
var att = get.attitude(_status.event.player, target);
@@ -1744,9 +2069,9 @@ const skills = {
}
return att;
})
- .set("du", card.name == "du");
- "step 2";
- if (result && result.bool) {
+ .set("du", card.name == "du")
+ .forResult();
+ if (result.bool) {
var target = result.targets[0];
target.gain(card, "gain2");
if (get.color(card, false) == "black") target.addTempSkill("spduyi2");
@@ -1774,11 +2099,12 @@ const skills = {
audio: "zhuikong",
trigger: { player: "phaseDiscardBegin" },
direct: true,
- content() {
- "step 0";
- player.chooseDrawRecover("###" + get.prompt("spcangni") + "###摸两张牌或回复1点体力,然后将武将牌翻面", 2).logSkill = "spcangni";
- "step 1";
- if (result.control != "cancel2") player.turnOver();
+ async content(event, trigger, player) {
+ const result = await player
+ .chooseDrawRecover("###" + get.prompt("spcangni") + "###摸两张牌或回复1点体力,然后将武将牌翻面", 2)
+ .set("logSkill", "spcangni")
+ .forResult();
+ if (result.control != "cancel2") await player.turnOver();
},
group: ["spcangni_gain", "spcangni_lose"],
subSkill: {
@@ -1856,30 +2182,25 @@ const skills = {
if (card.name == "sha") return 4;
return 4 - get.value(card);
},
- content() {
- "step 0";
- player.give(cards, targets[0]);
- "step 1";
+ async content(event, trigger, player) {
+ const targets = event.targets;
+ await player.give(event.cards, targets[0]);
if (!targets[0].isIn() || !targets[1].isIn()) {
- event.finish();
return;
}
- targets[0]
- .chooseToUse(
- function (card, player, event) {
- if (get.name(card) != "sha") return false;
- return lib.filter.filterCard.apply(this, arguments);
- },
- "密信:对" + get.translation(targets[1]) + "使用一张【杀】,或令其观看并获得你的一张手牌"
- )
+ const result = await targets[0]
+ .chooseToUse(function (card, player, event) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.filterCard.apply(this, arguments);
+ }, "密信:对" + get.translation(targets[1]) + "使用一张【杀】,或令其观看并获得你的一张手牌")
.set("complexSelect", true)
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.targetEnabled.apply(this, arguments);
})
- .set("sourcex", targets[1]);
- "step 2";
- if (!result.bool && targets[0].countCards("h")) targets[1].gainPlayerCard(targets[0], "visible", "h", true);
+ .set("sourcex", targets[1])
+ .forResult();
+ if (!result.bool && targets[0].countCards("h")) await targets[1].gainPlayerCard(targets[0], "visible", "h", true);
},
ai: {
order: 1,
@@ -1914,9 +2235,8 @@ const skills = {
}) > 0
);
},
- content() {
- "step 0";
- player
+ async content(event, trigger, player) {
+ const result = await player
.chooseCard("h", get.prompt("spfengyin", trigger.player), "交给该角色一张【杀】并令其跳过出牌阶段和弃牌阶段", function (card, player) {
return get.name(card, player) == "sha";
})
@@ -1931,8 +2251,8 @@ const skills = {
if (trigger.player.countCards("hs") < trigger.player.hp) return false;
return true;
})()
- );
- "step 1";
+ )
+ .forResult();
if (result.bool) {
var target = trigger.player;
player.logSkill("spfengyin", target);
diff --git a/character/collab/sort.js b/character/collab/sort.js
index ac0e9b39f..ea731ce76 100644
--- a/character/collab/sort.js
+++ b/character/collab/sort.js
@@ -1,17 +1,19 @@
const characterSort = {
collab_olympic: ["sunyang", "yeshiwen"],
collab_tongque: ["sp_fuwan", "sp_fuhuanghou", "sp_jiben", "old_lingju", "sp_mushun"],
- collab_duanwu: ["sunwukong", "longwang", "taoshen"],
+ collab_duanwu_2023: ["sunwukong", "longwang", "taoshen"],
collab_decade: ["libai", "xiaoyuehankehan", "zhutiexiong", "wu_zhutiexiong"],
collab_remake: ["dc_caocao", "dc_liubei", "dc_sunquan", "nezha", "dc_sunce", "dc_zhaoyun", "dc_wuyi"],
+ collab_duanwu_2024: ["quyuan", "xin_sunquan"],
};
const characterSortTranslate = {
collab_olympic: "OL·伦敦奥运会",
collab_tongque: "OL·铜雀台",
- collab_duanwu: "新服·端午畅玩",
+ collab_duanwu_2023: "新服·端午畅玩2023",
collab_decade: "新服·创玩节",
collab_remake: "新服·共创武将",
+ collab_duanwu_2024: "新服·端午畅玩2024",
};
export { characterSort, characterSortTranslate };
diff --git a/character/collab/translate.js b/character/collab/translate.js
index 43969a5e6..63d513648 100644
--- a/character/collab/translate.js
+++ b/character/collab/translate.js
@@ -99,6 +99,17 @@ const translates = {
dc_wuyi_prefix: "经典",
dcbenxi: "奔袭",
dcbenxi_info: "转换技,锁定技。当你失去手牌后,阴:系统随机检索出一句转换为拼音后包含“wu,yi”的技能台词,然后你念出此台词。阳:你获得上次所念出的台词对应的技能;若你已拥有该技能,则改为对其他角色各造成1点伤害。",
+ quyuan: "屈原",
+ dcqiusuo: "求索",
+ dcqiusuo_info: "当你造成伤害后,你可以从牌堆或弃牌堆中获得一张【铁索连环】。",
+ dclisao: "离骚",
+ dclisao_info: "出牌阶段限一次,你可以选择至多两名角色,这些角色须同时回答《离骚》的句段填空。第一名回答正确的角色展示所有手牌,所有本次回答错误或未回答的角色本回合受到伤害时,若其本回合已受到过伤害,则此伤害值改为上一次受到的伤害的两倍。",
+ xin_sunquan: "会玩孙权",
+ xin_sunquan_ab: "孙权",
+ dchuiwan: "会玩",
+ dchuiwan_info: "每回合每种牌名限一次,当你摸牌时,你可以放弃摸牌并改为选择至多等同于摸牌数的基本牌或锦囊牌的牌名,然后你从牌堆中获得这些牌名的牌。",
+ dchuanli: "唤理",
+ dchuanli_info: "结束阶段,若你本回合:使用牌至少指定三次自己为目标,则你可以令一名其他角色的所有技能失效,然后其获得〖直谏〗和〖固政〗,直到其下回合结束;使用牌至少指定三次一名其他角色为目标,则你可以令其所有技能失效,然后其获得〖英姿〗和〖反间〗,直到其下回合结束。然后若你两项均执行,你获得〖制衡〗直到你的下个回合结束。",
};
export default translates;
diff --git a/character/collab/voices.js b/character/collab/voices.js
index 501b0e03a..26e6de16e 100644
--- a/character/collab/voices.js
+++ b/character/collab/voices.js
@@ -45,4 +45,9 @@ export default {
"#taoshen:die": "马革裹尸,身沉江心……",
"#jieyuan_more": "我所有的努力,都是为了杀你!",
"#jieyuan_less": "我必须活下去!",
+ "#dchuiwan1": "金珠弹黄鹂,玉带做秋千,如此游戏人间。",
+ "#dchuiwan2": "小爷横行江东,今日走马、明日弄鹰。",
+ "#dchuanli1": "金乌当空,汝欲与我辩日否?",
+ "#dchuanli2": "童言无忌,童言有理!",
+ "#xin_sunquan:die": "阿娘,大哥抢我糖人!",
};
diff --git a/character/diy/skill.js b/character/diy/skill.js
index 2db429859..77580b666 100644
--- a/character/diy/skill.js
+++ b/character/diy/skill.js
@@ -5210,6 +5210,19 @@ const skills = {
subSkill: {
used: {},
},
+ ai: {
+ effect: {
+ target(card, player, target) {
+ if (get.tag(card, "save")) {
+ if (_status.currentPhase == player) return 0;
+ if (target.maxHp > 1 && player != target) return 0;
+ }
+ if (get.tag(card, "recover")) {
+ if (_status.currentPhase == player) return 0;
+ }
+ },
+ },
+ }
},
nsshishou: {
trigger: { player: "loseEnd" },
@@ -5241,18 +5254,7 @@ const skills = {
},
},
ai: {
- halfneg: true,
- effect: {
- target(card, player, target) {
- if (get.tag(card, "save")) {
- if (_status.currentPhase == player) return 0;
- if (target.maxHp > 1 && player != target) return 0;
- }
- if (get.tag(card, "recover")) {
- if (_status.currentPhase == player) return 0;
- }
- },
- },
+ neg: true,
},
},
nsduijue: {
diff --git a/character/extra/skill.js b/character/extra/skill.js
index 77bbbf2b0..07fb96d74 100644
--- a/character/extra/skill.js
+++ b/character/extra/skill.js
@@ -1438,9 +1438,9 @@ const skills = {
var info = lib.character[name];
if (
info[3].some(function (skill) {
- var info = get.skillInfoTranslation(skill);
+ var info = get.plainText(get.skillInfoTranslation(skill));
if (!info.includes("【杀】")) return false;
- var list = get.skillCategoriesOf(skill);
+ var list = get.skillCategoriesOf(skill, player);
list.remove("锁定技");
return list.length == 0;
})
@@ -1470,9 +1470,9 @@ const skills = {
var name = button.link;
var info = lib.character[name];
var skills = info[3].filter(function (skill) {
- var info = get.skillInfoTranslation(skill);
+ var info = get.plainText(get.skillInfoTranslation(skill));
if (!info.includes("【杀】")) return false;
- var list = get.skillCategoriesOf(skill);
+ var list = get.skillCategoriesOf(skill, get.player());
list.remove("锁定技");
return list.length == 0;
});
@@ -1509,9 +1509,9 @@ const skills = {
node = ui.create.buttonPresets.character(item, "character", position, noclick);
const info = lib.character[item];
const skills = info[3].filter(function (skill) {
- var info = get.skillInfoTranslation(skill);
+ var info = get.plainText(get.skillInfoTranslation(skill));
if (!info.includes("【杀】")) return false;
- var list = get.skillCategoriesOf(skill);
+ var list = get.skillCategoriesOf(skill, get.player());
list.remove("锁定技");
return list.length == 0;
});
@@ -1588,9 +1588,9 @@ const skills = {
var maxHp = get.infoMaxHp(info[2]);
if (maxHp != 1) card.distance = { attackFrom: 1 - maxHp };
var skills = info[3].filter(function (skill) {
- var info = get.skillInfoTranslation(skill);
+ var info = get.plainText(get.skillInfoTranslation(skill));
if (!info.includes("【杀】")) return false;
- var list = get.skillCategoriesOf(skill);
+ var list = get.skillCategoriesOf(skill, get.player());
list.remove("锁定技");
return list.length == 0;
});
@@ -1617,10 +1617,10 @@ const skills = {
if (skills.length) {
for (var skill of skills) {
if (lib.skill[skill].nobracket) {
- append += '' + get.translation(skill) + '
' + get.skillInfoTranslation(skill) + "
";
+ append += '' + get.translation(skill) + '
' + get.plainText(get.skillInfoTranslation(skill)) + "
";
} else {
var translation = lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2);
- append += '【' + translation + '】
' + get.skillInfoTranslation(skill) + "
";
+ append += '【' + translation + '】
' + get.plainText(get.skillInfoTranslation(skill)) + "
";
}
}
str = str.slice(0, str.length - 8);
@@ -1992,7 +1992,17 @@ const skills = {
},
},
ai: {
- combo: "dctuoyu",
+ effect: {
+ player(card, player, target) {
+ if (
+ !get.tag(card, "damage") ||
+ player.countMark("dcxianjin") % 2 ||
+ !player.hasSkillTag("jueqing", false, target)
+ ) return;
+ if (player.isMaxHandcard()) return [1, 1];
+ return [1, Math.min(3, 1 + player.getStorage("dctuoyu").length)];
+ }
+ }
},
},
dcqijing: {
@@ -3757,6 +3767,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "yuheng"
+ },
},
yuheng: {
audio: 2,
@@ -5766,22 +5779,25 @@ const skills = {
notemp: true,
effect: {
target: (card, player, target) => {
- if (!get.tag(card, "damage") || !target.hasFriend()) return;
- if (player.hasSkillTag("jueqing", null, target)) return 1.7;
+ if (!target.hasFriend()) return;
+ let rec = get.tag(card, "recover"), damage = get.tag(card, "damage");
+ if (!rec && !damage) return;
+ if (damage && player.hasSkillTag("jueqing", false, target)) return 1.7;
let die = [null, 1],
temp;
game.filterPlayer(i => {
temp = i.countMark("new_wuhun");
if (i === player && target.hp + target.hujia > 1) temp++;
- if (temp >= die[1]) {
+ if (temp > die[1]) die = [i, temp];
+ else if (temp === die[1]) {
if (!die[0]) die = [i, temp];
- else {
- let att = get.attitude(player, i);
- if (att < die[1]) die = [i, temp];
- }
+ else if (get.attitude(target, i) < get.attitude(target, die[0])) die = [i, temp];
}
});
- if (die[0]) return [1, 0, 1, (-6 * get.sgnAttitude(player, die[0])) / Math.max(1, target.hp)];
+ if (die[0]) {
+ if (damage) return [1, 0, 1, (-6 * get.sgnAttitude(player, die[0])) / Math.max(1, target.hp)];
+ return [1, (6 * get.sgnAttitude(player, die[0])) / Math.max(1, target.hp)];
+ }
},
},
},
@@ -6730,7 +6746,7 @@ const skills = {
target(card, player, target, current) {
if (player.getHp() <= 0) return;
if (!target.hasFriend()) return;
- if (target.hp <= 1 && get.tag(card, "damage")) return [1, 0, 0, -2];
+ if (target.hp <= 1 && get.tag(card, "damage")) return [1, 0, 0, -2 * player.getHp()];
},
},
},
diff --git a/character/hearth.js b/character/hearth.js
index 61df42fc2..239e44c88 100644
--- a/character/hearth.js
+++ b/character/hearth.js
@@ -2200,17 +2200,6 @@ game.import("character", function () {
content() {
trigger.num++;
},
- },
- qingtian_old: {
- trigger: { player: "recoverBefore" },
- forced: true,
- filter(event, player) {
- return player.hp > 0 && event.num > 0;
- },
- content() {
- trigger.cancel();
- player.changeHujia(trigger.num);
- },
ai: {
neg: true,
},
diff --git a/character/huicui/character.js b/character/huicui/character.js
index 593f091a8..ef4a78ab2 100644
--- a/character/huicui/character.js
+++ b/character/huicui/character.js
@@ -1,11 +1,11 @@
const characters = {
+ dc_sp_zhurong: ["female", "qun", 4, ["dcmanhou"]],
+ yue_zhugeguo: ["female", "shu", 3, ["dcxidi", "dcchengyan"]],
+ yue_zoushi: ["female", "qun", 3, ["dcyunzheng", "dchuoxin"]],
+ yue_miheng: ["male", "qun", 3, ["dcjigu", "dcsirui"]],
dc_lifeng: ["male", "shu", 3, ["dctunchu", "dcshuliang"]],
wupu: ["male", "qun", 4, ["dcduanti", "dcshicao"]],
- dc_caoshuang: ["male", "wei", 4, ["dcjianzhuan", "dcfanshi"]],
zangba: ["male", "wei", 4, ["rehengjiang"]],
- dc_simashi: ["male", "wei", 3, ["dcsanshi", "dczhenrao", "dcchenlve"]],
- dc_wangling: ["male", "wei", 4, ["dcjichou", "dcmouli"], ["clan:太原王氏"]],
- dc_jiangji: ["male", "wei", 3, ["dcshiju", "dcyingshi"]],
gongsunxiu: ["male", "qun", 4, ["dcgangu", "dckuizhen"]],
dc_liuli: ["male", "shu", 3, ["dcfuli", "dcdehua"]],
yue_daqiao: ["female", "wu", 3, ["dcqiqin", "dczixi"]],
@@ -47,7 +47,7 @@ const characters = {
dc_sp_jiaxu: ["male", "wei", 3, ["zhenlue", "dcjianshu", "dcyongdi"]],
leibo: ["male", "qun", 4, ["dcsilve", "dcshuaijie"]],
gongsundu: ["male", "qun", 4, ["dczhenze", "dcanliao"]],
- panghui: ["male", "wei", 5, ["dcyiyong"]],
+ panghui: ["male", "wei", 5, ["dcyiyong", "dcsuchou"]],
dc_yuejiu: ["male", "qun", 4, ["dccuijin"]],
chenjiao: ["male", "wei", 3, ["dcxieshou", "dcqingyan", "dcqizi"]],
wanglie: ["male", "qun", 3, ["dcchongwang", "dchuagui"]],
diff --git a/character/huicui/characterReplace.js b/character/huicui/characterReplace.js
index 1f982bd59..e5f981807 100644
--- a/character/huicui/characterReplace.js
+++ b/character/huicui/characterReplace.js
@@ -1,5 +1,6 @@
const characterReplaces = {
lifeng: ["dc_lifeng", "lifeng"],
+ zhugeguo: ["yue_zhugeguo", "zhugeguo"],
};
export default characterReplaces;
diff --git a/character/huicui/skill.js b/character/huicui/skill.js
index 8abd2113f..b5f530cc0 100644
--- a/character/huicui/skill.js
+++ b/character/huicui/skill.js
@@ -2,6 +2,513 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
+ //群祝融
+ dcmanhou: {
+ audio: 2,
+ enable: "phaseUse",
+ usable: 1,
+ chooseButton: {
+ dialog(event, player) {
+ return ui.create.dialog("###蛮后###选择一个数字,你可以摸等量张牌并执行等量项");
+ },
+ chooseControl(event, player) {
+ var list = Array.from({
+ length: 4,
+ }).map((_, i) => get.cnNumber(i + 1, true));
+ list.push("cancel2");
+ return list;
+ },
+ check(event, player) {
+ var list = Array.from({
+ length: 4,
+ }).map((_, i) => get.cnNumber(i + 1, true));
+ console.log(list);
+ if (get.effect(player, { name: "losehp" }, player, player) > 4 || player.countCards("hs", card => player.canSaveCard(card, player)) > 0 || player.hp > 2) return "四";
+ return "二";
+ },
+ backup(result, player) {
+ return {
+ num: result.control,
+ audio: "dcmanhou",
+ filterCard: () => false,
+ selectCard: -1,
+ async content(event, trigger, player) {
+ var num =
+ Array.from({
+ length: 4,
+ })
+ .map((_, i) => get.cnNumber(i + 1, true))
+ .indexOf(lib.skill.dcmanhou_backup.num) + 1;
+ await player.draw(num);
+ if (num >= 1) await player.removeSkills("dctanluan");
+ if (num >= 2 && player.countCards("h")) await player.chooseToDiscard("h", true);
+ if (num >= 3) await player.loseHp();
+ if (num >= 4) {
+ if (player.countCards("he")) await player.chooseToDiscard("he", true);
+ await player.addSkills("dctanluan");
+ }
+ },
+ };
+ },
+ },
+ ai: {
+ order: 8,
+ result: {
+ player: 1,
+ },
+ },
+ derivation: "dctanluan",
+ subSkill: {
+ backup: {},
+ },
+ },
+ dctanluan: {
+ audio: 2,
+ trigger: {
+ player: "useCardToPlayered",
+ },
+ filter(event, player) {
+ return event.isFirstTarget;
+ },
+ locked: true,
+ async cost(event, trigger, player) {
+ const num = trigger.targets.length,
+ num1 = game.filterPlayer(current => !trigger.targets.includes(current)).length;
+ if (num >= num1 && trigger.targets.some(current => current.countDiscardableCards(player, "ej"))) {
+ event.result = await player
+ .chooseTarget(get.prompt("dctanluan"), (card, player, target) => {
+ const evt = _status.event.getTrigger();
+ return evt.targets.includes(target) && target.countDiscardableCards(player, "ej");
+ })
+ .set("ai", target => {
+ const player = get.player();
+ const att = get.attitude(player, target);
+ if (
+ att > 0 &&
+ (target.countCards("j") > 0 ||
+ target.countCards("e", card => {
+ return get.value(card, target) < 0;
+ }))
+ )
+ return 2;
+ if (att < 0 && target.countCards("e") > 0 && !target.hasSkillTag("noe")) return -1;
+ return 0;
+ })
+ .forResult();
+ } else {
+ event.result = {
+ bool: true,
+ };
+ }
+ },
+ async content(event, trigger, player) {
+ if (event.targets && event.targets.length) await player.discardPlayerCard(event.targets[0], "ej", `弃置${get.translation(event.targets[0])}场上的一张牌`, true);
+ else player.addTempSkill("dctanluan_add");
+ },
+ subSkill: {
+ add: {
+ trigger: {
+ player: "useCard2",
+ },
+ async cost(event, trigger, player) {
+ player.removeSkill("dctanluan_add");
+ var goon = false;
+ var info = get.info(trigger.card);
+ if (!["basic", "trick"].includes(get.type(trigger.card))) return;
+ if (trigger.targets && !info.multitarget) {
+ if (
+ game.hasPlayer(function (current) {
+ return !trigger.targets.includes(current) && lib.filter.targetEnabled2(trigger.card, player, current);
+ })
+ ) {
+ goon = true;
+ }
+ }
+ if (!goon) return;
+ event.result = await player
+ .chooseTarget("是否发动【探乱】?", `为${get.translation(trigger.card)}添加一个目标`, (card, player, target) => {
+ const evt = _status.event.getTrigger();
+ return !evt.targets.includes(target) && lib.filter.targetEnabled2(evt.card, player, target);
+ })
+ .set("ai", target => {
+ return get.effect(target, _status.event.getTrigger().card, get.player());
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const targets = event.targets;
+ player.line(targets, "green");
+ trigger.targets.addArray(targets);
+ },
+ },
+ },
+ },
+ //乐诸葛果
+ dcxidi: {
+ audio: 2,
+ trigger: {
+ global: "phaseBefore",
+ player: "enterGame",
+ },
+ filter(event, player) {
+ return event.name != "phase" || game.phaseNumber == 0;
+ },
+ forced: true,
+ content() {
+ const cards = player.getCards("h");
+ player.addGaintag(cards, "dcxidi_tag");
+ },
+ mod: {
+ ignoredHandcard(card) {
+ if (card.hasGaintag("dcxidi_tag")) return true;
+ },
+ cardDiscardable(card, _, name) {
+ if (name == "phaseDiscard" && card.hasGaintag("dcxidi_tag")) return false;
+ },
+ },
+ group: "dcxidi_guanxing",
+ subSkill: {
+ guanxing: {
+ audio: "dcxidi",
+ trigger: { player: "phaseZhunbeiBegin" },
+ filter(event, player) {
+ return player.hasCard(card => card.hasGaintag("dcxidi_tag"), "h");
+ },
+ forced: true,
+ locked: false,
+ preHidden: true,
+ async content(event, trigger, player) {
+ const num = player.countCards("h", card => card.hasGaintag("dcxidi_tag"));
+ const cards = get.cards(Math.min(num, 5));
+ await game.cardsGotoOrdering(cards);
+ const next = player.chooseToMove();
+ next.set("list", [["牌堆顶", cards], ["牌堆底"]]);
+ next.set("prompt", "羲笛:点击将牌移动到牌堆顶或牌堆底");
+ next.processAI = list => {
+ const cards = list[0][1],
+ player = _status.event.player;
+ const top = [];
+ const judges = player.getCards("j");
+ let stopped = false;
+ if (!player.hasWuxie()) {
+ for (let i = 0; i < judges.length; i++) {
+ const judge = get.judge(judges[i]);
+ cards.sort((a, b) => judge(b) - judge(a));
+ if (judge(cards[0]) < 0) {
+ stopped = true;
+ break;
+ } else {
+ top.unshift(cards.shift());
+ }
+ }
+ }
+ let bottom;
+ if (!stopped) {
+ cards.sort((a, b) => get.value(b, player) - get.value(a, player));
+ while (cards.length) {
+ if (get.value(cards[0], player) <= 5) break;
+ top.unshift(cards.shift());
+ }
+ }
+ bottom = cards;
+ return [top, bottom];
+ };
+ const {
+ result: { moved },
+ } = await next;
+ const top = moved[0];
+ const bottom = moved[1];
+ top.reverse();
+ await game.cardsGotoPile(top.concat(bottom), ["top_cards", top], (event, card) => {
+ if (event.top_cards.includes(card)) return ui.cardPile.firstChild;
+ return null;
+ });
+ player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下");
+ game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶");
+ await game.asyncDelayx();
+ },
+ },
+ },
+ },
+ dcchengyan: {
+ audio: 2,
+ trigger: { player: "useCardToPlayered" },
+ filter(event, player) {
+ if (!player.isPhaseUsing()) return false;
+ if (event.card.name != "sha" && get.type(event.card) != "trick") return false;
+ return event.target != player;
+ },
+ logTarget: "target",
+ async content(event, trigger, player) {
+ const target = trigger.target;
+ const cards = get.cards();
+ await game.cardsGotoOrdering(cards);
+ await player.showCards(cards, get.translation(player) + "发动了【乘烟】");
+ const card = cards[0];
+ if (card.name == "sha" || (get.type(card) == "trick" && get.info(card).filterTarget)) {
+ player.addTempSkill("dcchengyan_effect");
+ player.markAuto("dcchengyan_effect", [[trigger.card, card, target]]);
+ }
+ if (card.name != "sha" && get.type(card) != "trick") {
+ await player.gain(card, "gain2").set("gaintag", ["dcxidi_tag"]);
+ }
+ else await game.cardsDiscard(cards);
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ onremove: true,
+ trigger: { player: "useCardToBegin" },
+ filter(event, player) {
+ const storage = player.getStorage("dcchengyan_effect");
+ return storage.some(list => list[0] == event.card && list[2] == event.target);
+ },
+ forced: true,
+ popup: false,
+ firstDo: true,
+ async content(event, trigger, player) {
+ const list = player.getStorage("dcchengyan_effect").find(list => list[0] == trigger.card && list[2] == trigger.target);
+ trigger.setContent(lib.card[list[1].name].content);
+ },
+ },
+ },
+ },
+ //乐邹氏
+ dcyunzheng: {
+ audio: 2,
+ trigger: {
+ global: "phaseBefore",
+ player: "enterGame",
+ },
+ filter(event, player) {
+ return event.name != "phase" || game.phaseNumber == 0;
+ },
+ forced: true,
+ content() {
+ const cards = player.getCards("h");
+ player.addGaintag(cards, "dcyunzheng_tag");
+ },
+ mod: {
+ ignoredHandcard(card) {
+ if (card.hasGaintag("dcyunzheng_tag")) return true;
+ },
+ cardDiscardable(card, _, name) {
+ if (name == "phaseDiscard" && card.hasGaintag("dcyunzheng_tag")) return false;
+ },
+ },
+ group: "dcyunzheng_fengyin",
+ subSkill: {
+ fengyin: {
+ audio: "dcyunzheng",
+ trigger: {
+ global: ["phaseBefore", "loseAfter", "loseAsyncAfter", "gainAfter", "equipAfter", "addJudgeAfter", "addToExpansionAfter"],
+ player: ["dchuoxin_update", "enterGame"],
+ },
+ filter(event, player) {
+ if (
+ ["lose", "loseAsync", "gain", "equip", "addJudge", "addToExpansion"].includes(event.name) &&
+ !game.hasPlayer(target => {
+ const evt = event.getl(target);
+ return evt && (evt.hs || []).length;
+ })
+ )
+ return false;
+ return game.hasPlayer(target => {
+ return target.hasCard(card => card.hasGaintag("dcyunzheng_tag"), "h") == !target.hasSkill("dcyunzheng_block");
+ });
+ },
+ logTarget(event, player) {
+ return game
+ .filterPlayer(target => {
+ return target.hasCard(card => card.hasGaintag("dcyunzheng_tag"), "h") == !target.hasSkill("dcyunzheng_block");
+ })
+ .sortBySeat();
+ },
+ forced: true,
+ content() {
+ const targets = game
+ .filterPlayer(target => {
+ return target.hasCard(card => card.hasGaintag("dcyunzheng_tag"), "h") == !target.hasSkill("dcyunzheng_block");
+ })
+ .sortBySeat();
+ for (const target of targets) {
+ target[target.hasSkill("dcyunzheng_block") ? "removeSkill" : "addSkill"]("dcyunzheng_block");
+ }
+ },
+ },
+ block: {
+ inherit: "fengyin",
+ },
+ },
+ },
+ dchuoxin: {
+ audio: 2,
+ trigger: { player: "useCardToPlayered" },
+ filter(event, player) {
+ if (
+ !player.hasHistory("lose", evt => {
+ if (evt.getParent() != event.getParent()) return false;
+ return event.cards.some(card => (evt.hs || []).includes(card));
+ })
+ )
+ return false;
+ return event.target != player && event.target.countCards("h");
+ },
+ forced: true,
+ logTarget: "target",
+ async content(event, trigger, player) {
+ const target = trigger.target;
+ const result = await player.choosePlayerCard("h", target, true, "惑心:展示" + get.translation(target) + "的一张手牌").forResult();
+ if (result.bool) {
+ let cards = result.cards.slice();
+ await player.showCards(cards, get.translation(player) + "发动了【惑心】");
+ const cardx = cards.filter(card => card.hasGaintag("dcyunzheng_tag") || get.suit(card) == get.suit(trigger.card));
+ if (cardx.length) {
+ cards.removeArray(cardx);
+ await player.gain(cardx, target, "give");
+ await event.trigger("dchuoxin_update");
+ }
+ if (cards.some(card => !card.hasGaintag("dcyunzheng_tag"))) {
+ target.addGaintag(
+ cards.filter(card => !card.hasGaintag("dcyunzheng_tag")),
+ "dcyunzheng_tag"
+ );
+ await event.trigger("dchuoxin_update");
+ }
+ }
+ },
+ },
+ //乐祢衡
+ dcjigu: {
+ audio: 2,
+ trigger: {
+ global: "phaseBefore",
+ player: "enterGame",
+ },
+ filter(event, player) {
+ return event.name != "phase" || game.phaseNumber == 0;
+ },
+ forced: true,
+ content() {
+ const cards = player.getCards("h");
+ player.addGaintag(cards, "dcjigu");
+ },
+ mod: {
+ ignoredHandcard(card) {
+ if (card.hasGaintag("dcjigu")) return true;
+ },
+ cardDiscardable(card, _, name) {
+ if (name == "phaseDiscard" && card.hasGaintag("dcjigu")) return false;
+ },
+ },
+ group: "dcjigu_temp",
+ subSkill: {
+ temp: {
+ audio: "dcjigu",
+ trigger: {
+ player: "damageEnd",
+ source: "damageSource",
+ },
+ filter(event, player) {
+ return player.countCards("e") == player.countCards("h", card => card.hasGaintag("dcjigu"));
+ },
+ usable: 1,
+ prompt2(event, player) {
+ return (
+ "摸" +
+ get.cnNumber(
+ Array.from({ length: 5 })
+ .map((_, i) => i + 1)
+ .reduce((sum, i) => sum + player.countEmptySlot(i), 0)
+ ) +
+ "张牌"
+ );
+ },
+ content() {
+ player.draw(
+ Array.from({ length: 5 })
+ .map((_, i) => i + 1)
+ .reduce((sum, i) => sum + player.countEmptySlot(i), 0)
+ );
+ },
+ },
+ },
+ },
+ dcsirui: {
+ audio: 2,
+ enable: "phaseUse",
+ filter(event, player) {
+ if (!player.countCards("hes")) return false;
+ return get
+ .inpileVCardList(info => {
+ const name = info[2];
+ if (get.type(name) != "basic" && get.type(name) != "trick") return false;
+ return true;
+ })
+ .some(card => player.hasCard(cardx => get.cardNameLength(cardx) == get.cardNameLength(card[2]) && event.filterCard({ name: card[2], nature: card[3], cards: [cardx] }, player, event), "hes"));
+ },
+ usable: 1,
+ chooseButton: {
+ dialog(event, player) {
+ const list = get
+ .inpileVCardList(info => {
+ const name = info[2];
+ if (get.type(name) != "basic" && get.type(name) != "trick") return false;
+ return true;
+ })
+ .filter(card => player.hasCard(cardx => get.cardNameLength(cardx) == get.cardNameLength(card[2]) && event.filterCard({ name: card[2], nature: card[3], cards: [cardx] }, player, event), "hes"));
+ return ui.create.dialog("思锐", [list, "vcard"]);
+ },
+ check(button) {
+ return get.event("player").getUseValue({
+ name: button.link[2],
+ nature: button.link[3],
+ });
+ },
+ backup(links, player) {
+ return {
+ audio: "dcsirui",
+ filterCard(card, player) {
+ return get.cardNameLength(card) == get.cardNameLength(lib.skill.dcsirui_backup.viewAs.name);
+ },
+ popname: true,
+ viewAs: {
+ name: links[0][2],
+ nature: links[0][3],
+ },
+ check(card) {
+ return 7 - get.value(card);
+ },
+ position: "hes",
+ };
+ },
+ prompt(links, player) {
+ return "将一张字数为" + get.cardNameLength(links[0][2]) + "的牌当作" + get.translation(links[0][3] || "") + "【" + get.translation(links[0][2]) + "】使用";
+ },
+ },
+ ai: {
+ order(item, player) {
+ let list = get
+ .inpileVCardList(info => {
+ const name = info[2];
+ if (get.type(name) != "basic" && get.type(name) != "trick") return false;
+ return true;
+ })
+ .filter(card => player.hasCard(cardx => get.cardNameLength(cardx) == get.cardNameLength(card[2]) && player.hasUseTarget(get.autoViewAs({ name: card[2], nature: card[3] }, [cardx]), true, true), "hes"))
+ .map(card => {
+ return { name: card[2], nature: card[3] };
+ })
+ .filter(card => player.getUseValue(card, true, true) > 0);
+ if (!list.length) return 0;
+ list.sort((a, b) => (player.getUseValue(b, true, true) || 0) - (player.getUseValue(a, true, true) || 0));
+ return get.order(list[0], player) * 0.99;
+ },
+ result: { player: 1 },
+ },
+ subSkill: {
+ backup: { audio: "dcsirui" },
+ },
+ },
//李丰
dctunchu: {
audio: 2,
@@ -1312,27 +1819,32 @@ const skills = {
cards.reduce((sum, card) => sum + get.cardNameLength(card), 0)
);
if (num) await player.draw(num);
- if (cards.some(card => card.name != "shandian" && get.tag(card, "damage"))) {
- const {
- result: { bool, targets },
- } = await player.chooseTarget("抚黎:是否令一名角色的攻击范围-1直到你的下个回合开始?").set("ai", target => {
+ const goon = cards.some(card => card.name != "shandian" && get.tag(card, "damage"));
+ const {
+ result: { bool, targets },
+ } = await player
+ .chooseTarget("抚黎:是否令一名角色的攻击范围" + (goon ? "减至0" : "-1") + "直到你的下个回合开始?", (card, player, target) => {
+ return !get.event("goon") || target.getAttackRange() > 0;
+ })
+ .set("ai", target => {
const player = get.event("player"),
num = target.getAttackRange();
+ if (get.event("goon")) return -num;
return -get.sgn(get.attitude(player, target)) * (target.getAttackRange() + (num <= 0 ? -num + 0.5 : num));
- });
- if (bool) {
- const target = targets[0];
- player.line(target);
- target.addSkill("dcfuli_range");
- target.addMark("dcfuli_range", 1, false);
- player
- .when(["phaseBegin", "dieBegin"])
- .then(() => {
- target.removeMark("dcfuli_range", 1, false);
- if (!target.hasMark("dcfuli_range")) target.removeSkill("dcfuli_range");
- })
- .vars({ target: target });
- }
+ })
+ .set("goon", goon);
+ if (bool) {
+ const target = targets[0];
+ player.line(target);
+ target.addSkill("dcfuli_range");
+ target.addMark("dcfuli_range", goon ? target.getAttackRange() : 1, false);
+ player
+ .when(["phaseBegin", "dieBegin"])
+ .then(() => {
+ target.removeMark("dcfuli_range", 1, false);
+ if (!target.hasMark("dcfuli_range")) target.removeSkill("dcfuli_range");
+ })
+ .vars({ target: target });
}
}
}
@@ -1413,8 +1925,10 @@ const skills = {
const card = new lib.element.VCard({ name: name });
return get.tag(card, "damage") && !player.getStorage("dcdehua").includes(name);
})
- )
- player.removeSkills("dcdehua");
+ ) {
+ await player.removeSkills("dcdehua");
+ player.addSkill("dcdehua_hand");
+ }
},
mod: {
maxHandcard(player, num) {
@@ -1438,6 +1952,21 @@ const skills = {
return "手牌上限+" + storage.length + "
不能从手牌中使用" + get.translation(storage);
},
},
+ subSkill: {
+ hand: {
+ charlotte: true,
+ mark: true,
+ intro: { content: "伤害牌不计入手牌上限" },
+ mod: {
+ ignoredHandcard(card) {
+ if (get.tag(card, "damage")) return true;
+ },
+ cardDiscardable(card, _, name) {
+ if (name == "phaseDiscard" && get.tag(card, "damage")) return false;
+ },
+ },
+ },
+ },
},
//蒋琬费祎
dcshengxi: {
@@ -1568,12 +2097,12 @@ const skills = {
const card = player
.getCards("h", card => {
if (get.value(card) >= 7) return false;
- return card.hasGaintag("dcqiqin_tag") && game.hasPlayer(target => target.canAddJudge(get.autoViewAs({ name: "dczixi_" + name }, [card])));
+ return card.hasGaintag("dcqiqin_tag") && game.hasPlayer(target => target.canAddJudge(get.autoViewAs({ name: "dczixi_" + button.link }, [card])));
})
.sort((a, b) => get.value(a) - get.value(b))[0];
if (
game.hasPlayer(current => {
- return get.attitude(player, current) < 0 && lib.skill.dczixi.zixiList.some(name => current.canAddJudge(get.autoViewAs({ name: "dczixi_" + name }, [card])));
+ return get.attitude(player, current) < 0 && lib.skill.dczixi.zixiList.some(name => current.canAddJudge(get.autoViewAs({ name: "dczixi_" + button.link }, [card])));
})
)
return list.indexOf(button.link) + 1;
@@ -2165,7 +2694,7 @@ const skills = {
onremove: true,
content: function* (event, map) {
const player = map.player;
- const cards = [];
+ let cards = [];
const bannedTypes = [];
bannedTypes.addArray(event.cards.map(card => get.type2(card, player)));
bannedTypes.addArray(player.getStorage("dcliangxiu"));
@@ -2182,22 +2711,56 @@ const skills = {
}
if (cards.length >= 2) break;
}
- let result;
if (!cards.length) {
player.chat("没牌了…");
game.log("但是哪里都找不到没有符合条件的牌!");
event.finish();
return;
- } else if (cards.length == 1) result = { bool: true, links: cards };
- else result = yield player.chooseButton(["良秀:获得一张牌", cards], true).set("ai", get.buttonValue);
- if (result.bool) {
- const toGain = result.links;
- player.markAuto("dcliangxiu", get.type2(toGain[0], false));
- player.when({ global: "phaseChange" }).then(() => {
- player.unmarkSkill("dcliangxiu");
- });
- player.gain(toGain, "gain2");
}
+ if (_status.connectMode) game.broadcastAll(() => (_status.noclearcountdown = true));
+ let given_map = {};
+ while (cards.length) {
+ let result;
+ if (cards.length == 1) result = { bool: true, links: cards.slice() };
+ else {
+ result = yield player.chooseCardButton("良秀:请选择要分配的牌", cards, [1, cards.length], true).set("ai", button => {
+ if (!ui.selected.buttons.length) return get.buttonValue(button);
+ return 0;
+ });
+ }
+ const gives = result.links;
+ const result2 = yield player
+ .chooseTarget("选择获得" + get.translation(gives) + "的角色", cards.length == 1)
+ .set("ai", target => {
+ return get.attitude(get.event("player"), target) * get.sgn(get.sgn(get.event("goon")) + 0.5);
+ })
+ .set(
+ "goon",
+ gives.reduce((sum, card) => sum + get.value(card), 0)
+ );
+ if (result2.bool) {
+ cards.removeArray(gives);
+ const id = result2.targets[0].playerid;
+ if (!given_map[id]) given_map[id] = [];
+ given_map[id].addArray(gives);
+ }
+ }
+ if (_status.connectMode) game.broadcastAll(() => delete _status.noclearcountdown);
+ let list = [];
+ for (const i in given_map) {
+ const source = (_status.connectMode ? lib.playerOL : game.playerMap)[i];
+ player.line(source, "green");
+ game.log(source, "获得了", given_map[i]);
+ list.push([source, given_map[i]]);
+ }
+ yield game
+ .loseAsync({
+ gain_list: list,
+ giver: player,
+ animate: "gain2",
+ })
+ .setContent("gaincardMultiple");
+ game.delayx();
},
intro: {
content: "已因此技能获得过$牌",
@@ -2437,7 +3000,7 @@ const skills = {
return get.type(event.card) == "basic" && _status.currentPhase;
},
prompt2: function (event, player) {
- const num = player.countMark("dccaisi_more") + 1;
+ const num = Math.pow(2, player.countMark("dccaisi_more"));
return `从${player == _status.currentPhase ? "牌堆" : "弃牌"}堆中随机获得${get.cnNumber(num)}张非基本牌`;
},
content: function* (event, map) {
@@ -2445,7 +3008,7 @@ const skills = {
trigger = map.trigger;
const position = player == _status.currentPhase ? "cardPile" : "discardPile";
let cards = [],
- num = player.countMark("dccaisi_more") + 1;
+ num = Math.pow(2, player.countMark("dccaisi_more"));
while (num > 0) {
num--;
let card = get[position](card => get.type(card) != "basic" && !cards.includes(card));
@@ -2458,7 +3021,7 @@ const skills = {
game.log(`但是${position == "discardPile" ? "弃" : ""}牌堆里没有非基本牌!`);
}
const sum = player.getHistory("useSkill", evt => evt.skill == "dccaisi").length;
- if (sum < player.maxHp) {
+ if (sum <= player.maxHp) {
player.addTempSkill("dccaisi_more");
player.addMark("dccaisi_more", 1, false);
} else player.tempBanSkill("dccaisi");
@@ -3947,12 +4510,6 @@ const skills = {
//裴元绍
dcmoyu: {
audio: 2,
- init() {
- game.addGlobalSkill("dcmoyu_ai");
- },
- onremove() {
- if (!game.hasPlayer(i => i.hasSkill("dcmoyu"), true)) game.removeGlobalSkill("dcmoyu_ai");
- },
enable: "phaseUse",
filter(event, player) {
return game.hasPlayer(current => lib.skill.dcmoyu.filterTarget(null, player, current));
@@ -3962,7 +4519,7 @@ const skills = {
},
async content(event, trigger, player) {
const target = event.target;
- player.addTempSkill("dcmoyu_clear");
+ player.addTempSkill("dcmoyu_clear", "phaseUseAfter");
player.markAuto("dcmoyu_clear", [target]);
await player.gainPlayerCard(target, "hej", true, 1 + player.hasSkill("dcmoyu_add"));
player.removeSkill("dcmoyu_add");
@@ -3979,10 +4536,6 @@ const skills = {
return lib.filter.targetEnabled.apply(this, arguments);
})
.set("sourcex", player)
- .set("num", num)
- .set("oncard", card => {
- _status.event.baseDamage = _status.event.getParent().num;
- })
.forResult();
if (result.bool) {
if (
@@ -3991,11 +4544,13 @@ const skills = {
})
) {
player.tempBanSkill("dcmoyu");
+ player.addTempSkill("dcmoyu_ban");
} else {
player.addTempSkill("dcmoyu_add", "phaseChange");
}
}
},
+ global: "dcmoyu_ai",
subSkill: {
clear: {
charlotte: true,
@@ -4004,7 +4559,7 @@ const skills = {
ban: {
charlotte: true,
mark: true,
- marktext: "欲",
+ marktext: '欲',
intro: { content: "偷马贼被反打了!" },
},
add: {
@@ -4014,15 +4569,6 @@ const skills = {
intro: { content: "欲望加速,下次抢两张!" },
},
ai: {
- trigger: { player: "dieAfter" },
- filter: () => {
- return !game.hasPlayer(i => i.hasSkill("dcmoyu"), true);
- },
- silent: true,
- forceDie: true,
- content: () => {
- game.removeGlobalSkill("dcmoyu_ai");
- },
ai: {
effect: {
target: function (card, player, target, current) {
@@ -5893,7 +6439,7 @@ const skills = {
}
},
ai: {
- combo: "dcaishou"
+ combo: "dcaishou",
},
},
//向朗
@@ -6998,13 +7544,62 @@ const skills = {
var num0 = getn(event.cards0),
num1 = getn(event.cards1);
if (num0 <= num1) {
- player.draw(event.cards1.length);
+ player.draw(event.cards1.length + 1);
}
if (num0 >= num1) {
trigger.num++;
}
},
},
+ dcsuchou: {
+ audio: 2,
+ trigger: { player: "phaseUseBegin" },
+ forced: true,
+ async content(event, trigger, player) {
+ const index = await player
+ .chooseControl()
+ .set("prompt", "夙仇:请选择一项")
+ .set("choiceList", ["失去1点体力,本阶段使用牌不可被响应", "减1点体力上限,本阶段使用牌不可被响应", "失去〖夙仇〗"])
+ .set("ai", () => {
+ const player = get.event("player");
+ if (player.isHealthy()) return player.maxHp <= 2 ? 3 : 0;
+ return 2;
+ })
+ .forResult("index");
+ switch (index) {
+ case 0:
+ await player.loseHp();
+ player.addTempSkill("dcsuchou_effect", "phaseUseAfter");
+ break;
+ case 1:
+ await player.loseMaxHp();
+ player.addTempSkill("dcsuchou_effect", "phaseUseAfter");
+ break;
+ case 2:
+ await player.removeSkills("dcsuchou");
+ break;
+ }
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ mark: true,
+ marktext: "仇",
+ intro: { content: "使用牌不可被响应" },
+ audio: "dcsuchou",
+ trigger: { player: "useCard" },
+ filter(event, player) {
+ return event.card.name == "sha" || get.type(event.card) == "trick";
+ },
+ forced: true,
+ content() {
+ trigger.directHit.addArray(game.players);
+ game.log(trigger.card, "不可被响应");
+ },
+ ai: { directHit_ai: true },
+ },
+ },
+ },
//乐就
dccuijin: {
audio: 2,
@@ -9665,6 +10260,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "zhishi"
+ },
},
zhishi: {
audio: 2,
@@ -13369,7 +13967,7 @@ const skills = {
}
},
ai: {
- combo: "recangchu"
+ combo: "recangchu",
},
},
reshishou: {
diff --git a/character/huicui/sort.js b/character/huicui/sort.js
index f540205c1..3a247da76 100644
--- a/character/huicui/sort.js
+++ b/character/huicui/sort.js
@@ -10,9 +10,9 @@ const characterSort = {
sp_yanhan: ["dc_lifeng", "dc_liuba", "dc_huangquan", "furongfuqian", "xianglang", "dc_huojun", "gaoxiang", "dc_wuban", "jiangfei"],
sp_jishi: ["dc_jiben", "zhenghun", "dc_sunhanhua", "liuchongluojun", "wupu"],
sp_raoting: ["dc_huanghao", "dc_sunziliufang", "dc_sunchen", "dc_jiachong"],
- sp_yijun: ["gongsundu", "mengyou", "dc_sp_menghuo", "gongsunxiu"],
- sp_zhengyin: ["yue_caiwenji", "yue_zhoufei", "yue_caiyong", "yue_xiaoqiao", "yue_daqiao"],
- sp_zhonghu: ["dc_jiangji", "dc_wangling", "dc_simashi", "dc_caoshuang"],
+ sp_yijun: ["gongsundu", "mengyou", "dc_sp_menghuo", "gongsunxiu", "dc_sp_zhurong"],
+ sp_zhengyin: ["yue_caiwenji", "yue_zhoufei", "yue_caiyong", "yue_xiaoqiao", "yue_daqiao", "yue_miheng", "yue_zoushi", "yue_zhugeguo"],
+ huicui_waitforsort: [],
};
const characterSortTranslate = {
@@ -29,7 +29,7 @@ const characterSortTranslate = {
sp_raoting: "绕庭之鸦",
sp_yijun: "异军突起",
sp_zhengyin: "正音雅乐",
- sp_zhonghu: "冢虎狼顾",
+ huicui_waitforsort: "等待分包",
};
export { characterSort, characterSortTranslate };
diff --git a/character/huicui/translate.js b/character/huicui/translate.js
index 221ee31d7..70ddd18ec 100644
--- a/character/huicui/translate.js
+++ b/character/huicui/translate.js
@@ -261,7 +261,9 @@ const translates = {
dccuijin_info: "当你或你攻击范围内的角色使用【杀】或【决斗】时,你可以弃置一张牌,令此牌的伤害基数+1。然后当此牌被目标角色抵消或无效或防止伤害后,你摸两张牌并对使用者造成1点伤害。",
panghui: "庞会",
dcyiyong: "异勇",
- dcyiyong_info: "当你对其他角色造成伤害时,若你有牌,你可以与其同时弃置至少一张牌。若你以此法弃置的牌的点数之和:不大于其,你摸X张牌;不小于其,此伤害+1(X为其以此法弃置的牌数)。",
+ dcyiyong_info: "当你对其他角色造成伤害时,若你有牌,你可以与其同时弃置至少一张牌。若你以此法弃置的牌的点数之和:不大于其,你摸X+1张牌;不小于其,此伤害+1(X为其以此法弃置的牌数)。",
+ dcsuchou: "夙仇",
+ dcsuchou_info: "锁定技,出牌阶段开始时,你选择一项:①失去1点体力或减1点体力上限,本阶段使用牌不可被响应;②失去〖夙仇〗。",
chenjiao: "陈矫",
dcxieshoux: "协守/清严",
dcxieshou: "协守",
@@ -435,7 +437,7 @@ const translates = {
dcshizong_info: "当你需要使用一张基本牌时,你可以交给一名其他角色X张牌,然后其可以将一张牌置于牌堆底,视为你使用之。若其不为当前回合角色,此技能失效直到回合结束(X为你本回合发动〖恃纵〗的次数)。",
pangshanmin: "庞山民",
dccaisi: "才思",
- dccaisi_info: "当你于回合内/回合外使用基本牌结算结束后,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后若你本回合发动此技能的次数:小于你的体力上限,本回合你发动此技能获得的牌数+1;大于等于你的体力上限,本回合此技能失效。",
+ dccaisi_info: "当你于回合内/回合外使用基本牌结算结束后,你可以从牌堆/弃牌堆随机获得一张非基本牌,然后若你本回合发动此技能的次数:小于等于你的体力上限,本回合你发动此技能获得的牌数翻倍;大于你的体力上限,本回合此技能失效。",
dczhuoli: "擢吏",
dczhuoli_info: "锁定技。一名角色的回合结束时,若你本回合使用或获得的牌数大于体力值,你加1点体力上限(不能超过游戏人数),回复1点体力。",
yue_caiyong: "乐蔡邕",
@@ -447,7 +449,7 @@ const translates = {
dcfeibai_info: "每回合限一次。当你使用牌结算结束后,若你本回合使用过至少两张牌,你可以随机获得一张字数为X的牌。若你的“弦”数不大于X,你重置〖飞白〗(X为此牌与你使用的上一张牌的字数之和)。",
kuaiqi: "蒯祺",
dcliangxiu: "良秀",
- dcliangxiu_info: "出牌阶段,你可以弃置两张不同类型的牌,然后从两张与你弃置的牌类型均不同的牌中选择一张获得之(每阶段每种类型限一次)。",
+ dcliangxiu_info: "出牌阶段每种类型限一次,你可以弃置两张不同类型的牌,然后你将牌堆或弃牌堆中的两张与你弃置的牌类型均不同的牌分配给任意角色。",
dcxunjie: "殉节",
dcxunjie_info: "每轮每项限一次。一名角色的回合结束时,若你本回合于摸牌阶段外得到过牌,你可以选择一项:1.令一名角色将手牌数摸或弃置至与其体力值相同;2.令一名角色将体力回复或失去至与其手牌数相同。",
dc_dongzhao: "董昭",
@@ -486,27 +488,24 @@ const translates = {
dcshoucheng_info: "每回合限一次,当一名角色于其回合外失去手牌后,若其没有手牌,你可令其摸两张牌。",
dc_liuli: "刘理",
dcfuli: "抚黎",
- dcfuli_info: "出牌阶段限一次,你可以展示手牌并弃置一种类别的所有手牌,然后摸X张牌(X为这些牌的牌名字数和且X至多为场上手牌数最多的角色的手牌数)。若你因此弃置了伤害类卡牌,则你可以选择一名角色,令其攻击范围-1直到你的下个回合开始。",
+ dcfuli_info: "出牌阶段限一次,你可以展示手牌并弃置一种类别的所有手牌,然后摸X张牌(X为这些牌的牌名字数和且X至多为场上手牌数最多的角色的手牌数)。然后你可以选择一名角色,令其攻击范围-X直到你的下个回合开始(X为1,若你因此弃置了伤害类卡牌,则X改为减其攻击范围)。",
dcdehua: "德化",
- dcdehua_info: "锁定技。①一轮游戏开始时,若有你可以使用的非延时类伤害类牌的牌名,你选择其中一个并视为使用之,然后你不能从手牌中使用此牌名的牌,然后若你已选择过所有的伤害类牌牌名,你失去〖德化〗。②你的手牌上限+Y(Y为你〖德化①〗选择过的牌名数)。",
+ dcdehua_info: "锁定技。①一轮游戏开始时,若有你可以使用的非延时类伤害类牌的牌名,你选择其中一个并视为使用之,然后你不能从手牌中使用此牌名的牌,然后若你已选择过所有的伤害类牌牌名,你失去〖德化〗,然后本局游戏你的伤害牌不计手牌上限。②你的手牌上限+Y(Y为你〖德化①〗选择过的牌名数)。",
gongsunxiu: "公孙修",
dcgangu: "干蛊",
dcgangu_info: "锁定技。每回合限一次。当其他角色失去体力后,你摸两张牌,然后失去1点体力。",
dckuizhen: "溃阵",
dckuizhen_info: "出牌阶段限一次。你可以令一名手牌数或体力值大于你的角色视为对你使用一张【决斗】。若你:受到渠道为此牌的伤害,你观看其手牌并获得其中所有的【杀】(你使用以此法得到的牌无任何次数限制);未受到渠道为此牌的伤害,其失去1点体力。",
- dc_jiangji: "蒋济",
dcshiju: "势举",
dcshiju_info: "其他角色的出牌阶段限一次。其可以交给你一张牌,若此牌为装备牌,你可以使用之,然后其本回合攻击范围+X(X为你装备区里的牌数)。若你以此法替换了装备,你与其各摸两张牌。",
dcyingshi: "应时",
dcyingshi_info: "每回合每项各限一次。当你使用普通锦囊牌指定目标后,你可令其中一个目标选择一项:⒈令你于此牌结算结束后视为对其使用一张与此牌牌名相同的牌;⒉弃置X张牌,此牌对其无效(X为你装备区里的牌数)。",
- dc_wangling: "王淩",
dcjichou: "集筹",
dcjichou_info: "出牌阶段结束时,若你于此阶段使用过牌且这些牌的牌名均不同,你可以观看位于弃牌堆中的这些牌,选择任意张牌并选择等量角色,将这些牌交给这些角色各一张,然后你摸X张牌(X为你本局游戏首次发动〖集筹〗给出的牌数)。",
dcmouli: "谋立",
dcmouli_info: "觉醒技。回合结束时,若你因〖集筹〗给出的牌的牌名总数大于5,你加1点体力上限并回复1点体力,然后获得〖自缚〗。",
dczifu: "自缚",
dczifu_info: "锁定技。出牌阶段开始时,你将手牌摸至体力上限(至多摸至五张)。若你以此法得到牌,你须选择手牌中不同牌名的牌各一张,然后弃置其余的手牌。",
- dc_simashi: "司马师",
dcsanshi: "散士",
dcsanshi_tag: "死士",
dcsanshi_info: "锁定技。①第一轮游戏开始时,你令系统将牌堆中每个点数的随机一张牌永久标记为“死士”(“死士”对你可见)。②一名角色的回合结束时,若本回合有“死士”不因你使用或打出而进入弃牌堆,你于弃牌堆中获得这些牌。③你使用“死士”不能被响应。",
@@ -514,8 +513,6 @@ const translates = {
dczhenrao_info: "每回合每名角色限一次。当你使用牌指定第一个目标后,若目标角色包含其他角色,或当其他角色使用牌指定你为目标后,你可以选择手牌数大于你的其中一个目标或此牌的使用者,然后对其造成1点伤害。",
dcchenlve: "沉略",
dcchenlve_info: "限定技。出牌阶段,你可以将牌堆、弃牌堆、场上及其他角色的手牌区里的所有“死士”置入处理区,然后你获得这些牌。若如此做,你获得如下效果:1.此回合结束时,你将这些牌移出游戏;2.当你死亡时,你将所有以此法移出游戏的“死士”置入弃牌堆。",
- dc_caoshuang: "新杀曹爽",
- dc_caoshuang_prefix: "新杀",
dcjianzhuan: "渐专",
dcjianzhuan_info: "锁定技。①当你于出牌阶段使用牌时,你选择此阶段未执行过的一项执行:⒈令一名角色弃置X张牌;⒉摸X张牌;⒊重铸X张牌;⒋弃置X张牌(X为此技能于本阶段的发动次数)。②出牌阶段结束时,若你本阶段执行过〖渐专①〗的所有选项,则你随机移除〖渐专①〗的一项。",
dcjianzhuan_faq: "渐专概率",
@@ -535,6 +532,32 @@ const translates = {
dctunchu_info: "锁定技。①游戏开始时,你将手牌数摸至游戏人数的四倍。②你的手牌不能被弃置。③准备阶段,若你的手牌数大于你的体力值,则你本回合至多使用三张牌。",
dcshuliang: "输粮",
dcshuliang_info: "一名角色的回合结束时,你可以将任意张手牌交给任意名没有手牌的角色各一张,然后本次获得可以指定自己为目标的牌的角色可以依次选择是否使用本次获得的牌。",
+ yue_miheng: "乐祢衡",
+ yue_miheng_prefix: "乐",
+ dcjigu: "激鼓",
+ dcjigu_info: "锁定技。①游戏开始时,你将所有手牌标记为“激鼓”。②你的“激鼓”牌不计入手牌上限。③每回合限一次,当你造成或受到伤害后,若你的你的“激鼓”牌数等于你的装备区的牌数,则你可以摸X张牌(X为你的空缺装备栏数)。",
+ dcsirui: "思锐",
+ dcsirui_info: "出牌阶段限一次,你可以将一张牌当作与其字数相同的一张基本牌或普通锦囊牌使用。",
+ yue_zoushi: "乐邹氏",
+ yue_zoushi_prefix: "乐",
+ dcyunzheng: "韵筝",
+ dcyunzheng_tag: "筝",
+ dcyunzheng_info: "锁定技。①游戏开始时,你将所有手牌标记为“筝”。②你的“筝”牌不计入手牌上限。③手牌中有“筝”的角色的非锁定技失效。",
+ dchuoxin: "惑心",
+ dchuoxin_info: "锁定技,当你使用手牌指定其他角色为目标后,你展示其一张手牌。若此牌为“筝”牌或与你使用牌花色相同,你获得之;否则你将此牌标记为“筝”。",
+ yue_zhugeguo: "乐诸葛果",
+ yue_zhugeguo_prefix: "乐",
+ dcxidi: "羲笛",
+ dcxidi_tag: "笛",
+ dcxidi_info: "锁定技。①游戏开始时,你将所有手牌标记为“笛”。②你的“笛”牌不计入手牌上限。③准备阶段,若你的手牌中有“笛”,则你观看牌堆顶X张牌,然后将这些牌以任意顺序置于牌堆顶和牌堆底(X为你手牌中的“笛”数,且X至多为5)。",
+ dcchengyan: "乘烟",
+ dcchengyan_info: "当你于出牌阶段使用【杀】或普通锦囊牌指定其他角色为目标后,你可以亮出牌堆顶的一张牌,若此牌为【杀】或可指定目标的普通锦囊牌,你将此牌对其的结算方式改为此牌牌名的结算方式;若此牌不为【杀】和普通锦囊牌,你获得此牌并将此牌标记为“笛”。",
+ dc_sp_zhurong: "新杀SP祝融",
+ dc_sp_zhurong_prefix: "新杀SP",
+ dcmanhou: "蛮后",
+ dcmanhou_info: "出牌阶段限一次,你可以摸任意张牌并依次执行以下等量项(至多为4) :1:失去〖探乱〗;2:弃置一张手牌; 3:失去1点体力; 4:弃置一张牌并获得〖探乱〗。",
+ dctanluan: "探乱",
+ dctanluan_info: "锁定技,你使用牌指定目标后,若目标角色数大于等于非目标角色数,你可以弃置其中一个目标角色场上的一张牌;若目标角色数小于非目标角色数,则本回合你使用下一张牌的目标数+1。",
};
export default translates;
diff --git a/character/huicui/voices.js b/character/huicui/voices.js
index f0cb93b05..0d8fb91e9 100644
--- a/character/huicui/voices.js
+++ b/character/huicui/voices.js
@@ -195,7 +195,9 @@ export default {
"#dcanliao2": "水草丰沛,当展宏图。",
"#gongsundu:die": "为何都不愿出仕!",
"#dcyiyong1": "关氏鼠辈,庞令明之子来邪!",
- "#dcyiyong2": "凭一腔勇力,父仇定可报还。",
+ "#dcyiyong2": "凭一腔勇力,父仇定可报还!",
+ "#dcsuchou1": "关家人我杀定了,谁也保不住!",
+ "#dcsuchou2": "身陷仇海,谁知道我是怎么过的!",
"#panghui:die": "大仇虽报,奈何心有余创……",
"#dccuijin1": "军令如山,诸君焉敢不前?",
"#dccuijin2": "前攻者赏之,后靡斩之!",
@@ -459,4 +461,9 @@ export default {
"#llqshenwei2": "红妆非我愿,学武觅封侯。",
"#wushuang_lvlingqi1": "猛将策良骥,长戟破敌营。",
"#wushuang_lvlingqi2": "杀气腾剑戟,严风卷戎装。",
+ "#dcjigu1": "我接着奏乐,诸公接着舞。",
+ "#dcjigu2": "这不是鼓,而是曹公的脸面!",
+ "#dcsirui1": "暑气可借酒气消,此间艳阳最佐酒。",
+ "#dcsirui2": "诸君饮泥而醉,举世唯我独醒!",
+ "#yue_miheng:die": "映日荷花今犹在,不见当年采荷人……",
};
diff --git a/character/jsrg/intro.js b/character/jsrg/intro.js
index d05ebd8c5..e977ec82b 100644
--- a/character/jsrg/intro.js
+++ b/character/jsrg/intro.js
@@ -15,6 +15,8 @@ const characterIntro = {
zhanghuan: "张奂(104-181年),字然明,又名张焕。敦煌渊泉今甘肃省瓜州县)人,后以功移籍弘农郡(今河南灵宝),书法家张芝的父亲。中国东汉经学家、军事家、文学家,“凉州三明”之一。早年师从太尉朱宠,研习《欧阳尚书》,自行删减《牟氏章句》。汉桓帝时,举贤良出身,对策第一,授议郎,历任安定都尉、武威太守、度辽将军、护匈奴中郎将等职。多次赢得对外战争,招抚外族,促进边境和平,功勋卓著。汉灵帝即位,迁大司农,受到宦官集团利用,讨伐大将军窦武。事后,上疏为窦武等人申冤。累迁太常卿,辞官归乡,授课著书,不再出仕。光和四年(181年),张奂去世,时年七十八。",
chenfan: "陈蕃(?-168年),字仲举。汝南平舆(今河南省平舆北)人。东汉时期名臣,与窦武、刘淑合称“三君”。陈蕃年少时有大志,举孝廉,授郎中。因母去世,辞官居丧。后由太尉李固荐举为乐安太守。因得罪大将军梁冀,由太守降为县令。为了零陵桂阳的流民山匪得罪皇帝身边的人,被外放为豫章太守。后升任大鸿胪。延熹六年(163年),陈蕃被征为尚书仆射,转太中大夫。延熹八年(165年),陈藩代杨秉为太尉,次年,被免官。永康元年(167年),汉桓帝去世,窦皇后临朝,以陈蕃为太傅,管理尚书事宜。次年,汉灵帝即位,陈藩与大将军窦武谋诛宦官,事泄,宦官曹节劫持汉灵帝与窦太后,诛杀窦武,又率宫中卫士包围了陈蕃,陈蕃率学士80人抵抗,被害,年七十余。",
zhangju: "张举(生卒年不详),渔阳人,与张纯同郡,是东汉末年起义军将领,曾在汉朝担任泰山太守。中平四年(187年),张举受张纯挑唆,联合乌桓起兵攻打郡县,部众到达了十多万;张举自称天子,张纯自称弥天将军安定王,声称自己将取代汉朝。刘虞担任幽州牧后,用怀柔之策说服乌桓罢兵,并悬赏求购张举、张纯;两人逃出塞外,后来张纯被门客王政所杀,张举则下落不明。",
+ caojiewangfu: "曹节(?―181年),字汉丰,南阳育阳(今河南省南阳市宛城区瓦店镇)人。东汉宦官。因事入宫,累迁西园骑。汉顺帝时期,迁小黄门。汉桓帝继位,迁中常侍,加任奉车都尉。拥戴汉灵帝有功,册封长安乡侯。联合长乐五官史朱瑀等矫诏诛杀窦武、陈蕃等人,升任长乐卫尉,进封育阳县侯。建宁二年(169年),加位特进、大长秋。权倾朝野,诬害勃海王刘悝,累迁尚书令。光和四年(181年),曹节去世,获赠车骑将军。
王甫(?—179年),东汉时期宦官。前十常侍之一。灵帝初为长乐食监,受中常侍曹节等矫诏为黄门令,将兵诛杀大将军窦武等人,因迁中常侍。后与节诬奏勃海王刘悝谋反,封冠军侯。由此操纵朝政,父兄子弟皆为公卿列校、牧守令长,布满天下。光和二年 (179),与养子永乐少府萌、沛相吉并为司隶校尉阳球收捕,磔尸于城门。",
+ songhuanghou: "孝灵宋皇后(?―178年),宋氏,名不详,世称“宋孝灵”,扶风平陵人,汉章帝刘炟妃子宋贵人堂曾孙女,执金吾宋酆之女。建宁三年(170年),宋氏入选掖庭,封为贵人。建宁四年(171年),汉灵帝立宋氏为皇后。宋皇后无宠,却正位中宫,后宫得宠的姬妾们便共同谮恶宋皇后,诬陷宋皇后行祝诅之事。汉灵帝听信其言,于光和元年(178年)策收宋氏的皇后玺绶。宋皇后自行前往暴室狱,忧死,其父、兄弟皆伏诛。各个常侍、小黄门在宫中的,都怜悯宋氏无辜,一同筹钱安葬宋皇后及宋酆父子于皋门亭宋氏旧茔。",
};
export default characterIntro;
diff --git a/character/jsrg/skill.js b/character/jsrg/skill.js
index 562474111..101b036a0 100644
--- a/character/jsrg/skill.js
+++ b/character/jsrg/skill.js
@@ -688,6 +688,7 @@ const skills = {
);
},
async content(event, trigger, player) {
+ player.awakenSkill("jsrgjiebing");
await player.gainMaxHp(2);
await player.recover(2);
await player.addSkills("jsrgbaowei");
@@ -987,7 +988,7 @@ const skills = {
sources.sortBySeat();
player.line(sources, "thunder");
for (let source of sources) {
- if (!source.isIn() || !target.isIn()) break;
+ if (!source.isIn() || !target.isIn()) continue;
target.damage(source, "thunder");
}
},
@@ -1834,6 +1835,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "jsrgjinfa"
+ },
},
jsrgxuanfeng: {
audio: 2,
@@ -1866,6 +1870,7 @@ const skills = {
},
ai: {
order: 2,
+ combo: "jsrgjinfa"
},
},
//陆逊
@@ -2920,6 +2925,9 @@ const skills = {
}
player.logSkill("jsrgbazheng", dissident);
},
+ ai: {
+ combo: "jsrgyaoyan"
+ },
},
//刘永
jsrgdanxin: {
@@ -8040,7 +8048,7 @@ const skills = {
})
.set("max", trigger.target.countDiscardableCards(player, "he"))
.set("goon", get.attitude(player, trigger.target) < 0)
- .set("logSkill", ["jsrgjuelie_discard", trigger.target]);
+ .set("logSkill", ["jsrgjuelie", trigger.target]);
("step 1");
if (result.bool) {
var num = result.cards.length;
@@ -9311,7 +9319,7 @@ const skills = {
aiValue: (player, card, num) => {
if (num > 0 && get.itemtype(card) === "card" && card.name !== "zhuge" && get.subtype(card) === "equip1" && !player.getEquip(1)) return 0.01 * num;
},
- aiUseful: () => {
+ aiUseful: function () {
return lib.skill.jsrgzhenqiao.mod.aiValue.apply(this, arguments);
},
},
@@ -9398,6 +9406,9 @@ const skills = {
target.damage();
}
},
+ ai: {
+ combo: "jsrgshelun"
+ },
},
jsrgtushe: {
audio: "xinfu_tushe",
diff --git a/character/jsrg/translate.js b/character/jsrg/translate.js
index f1d8be26f..a0e2d58da 100644
--- a/character/jsrg/translate.js
+++ b/character/jsrg/translate.js
@@ -370,9 +370,9 @@ const translates = {
jsrg_caojiewangfu: "衰曹节王甫",
jsrg_caojiewangfu_prefix: "衰",
jsrgzonghai: "纵害",
- jsrgzonghai_info: "每轮限一次。当有其他角色进入濒死状态时,你可以令其选择至多两名角色。未被选择的角色不能于此次濒死结算中使用牌,且此次濒死状态结算结束后,你对其选择的角色各造成1点伤害。",
+ jsrgzonghai_info: "每轮限一次。当有其他角色进入濒死状态时,你可以令其选择至多两名角色。未被选择的角色不能于此次濒死结算中使用牌,且此次濒死状态结算结束后,你对其选择的角色各造成1点伤害。",
jsrgjueyin: "绝禋",
- jsrgjueyin_info: "当你于一回合内首次收到伤害后,你可以摸三张牌,然后本回合内所有角色受到的伤害+1。",
+ jsrgjueyin_info: "当你于一回合内首次受到伤害后,你可以摸三张牌,然后本回合内所有角色受到的伤害+1。",
jsrg_songhuanghou: "衰宋皇后",
jsrg_songhuanghou_prefix: "衰",
jsrgzhongzen: "众谮",
diff --git a/character/jsrg/voices.js b/character/jsrg/voices.js
index 09505ebf7..f0aee4361 100644
--- a/character/jsrg/voices.js
+++ b/character/jsrg/voices.js
@@ -1,6 +1,6 @@
export default {
"#jsrg_zoushi:die": "年老色衰了吗?",
- "#jsrg_zhangren:die": "老臣,绝不事二主!",
+ "#jsrg_zhangren:die": "本将军败于诸葛,无憾!",
"#jsrg_huangzhong:die": "不得不服老啦~",
"#jsrg_liuhong:die": "权利的滋味,让人沉沦……",
};
diff --git a/character/key/skill.js b/character/key/skill.js
index aec651483..6d4e19198 100644
--- a/character/key/skill.js
+++ b/character/key/skill.js
@@ -8635,6 +8635,16 @@ const skills = {
},
},
riki_nvzhuang: {
+ init(player) {
+ if (get.character(player.name1, 3).includes("riki_nvzhuang")) {
+ player.storage.riki_nvzhuang = player.sex;
+ if (player.sex === "male") player.sex = "double";
+ else player.sex = "female";
+ }
+ },
+ onremove(player) {
+ if (player.storage.riki_nvzhuang) player.sex = player.storage.riki_nvzhuang;
+ },
trigger: { player: "phaseJieshuBegin" },
forced: true,
content() {
diff --git a/character/mobile/character.js b/character/mobile/character.js
index 8ab8d441f..7f22c751e 100644
--- a/character/mobile/character.js
+++ b/character/mobile/character.js
@@ -28,7 +28,7 @@ const characters = {
re_yanwen: ["male", "qun", 4, ["reshuangxiong"]],
xin_zhoutai: ["male", "wu", 4, ["buqu", "new_fenji"]],
re_caozhi: ["male", "wei", 3, ["reluoying", "rejiushi", "chengzhang"]],
- yj_weiyan: ["male", "qun", 5, ["mbguli", "mbaosi"]],
+ yj_weiyan: ["male", "qun", "4/4/1", ["mbguli", "mbaosi"]],
re_chenqun: ["male", "wei", 3, ["redingpin", "refaen"]],
xin_caoxiu: ["male", "wei", 4, ["qianju", "xinqingxi"]],
xin_zhuhuan: ["male", "wu", 4, ["fenli", "xinpingkou"]],
diff --git a/character/mobile/characterReplace.js b/character/mobile/characterReplace.js
index 45a2cf5ad..1bb76b62c 100644
--- a/character/mobile/characterReplace.js
+++ b/character/mobile/characterReplace.js
@@ -18,7 +18,8 @@ const characterReplaces = {
sunhanhua: ["dc_sunhanhua", "sunhanhua"],
zhoubuyi: ["zhoubuyi", "yj_zhoubuyi"],
xianglang: ["xianglang", "mb_xianglang"],
- miheng: ["re_miheng", "miheng"],
+ miheng: ["yue_miheng", "re_miheng", "miheng"],
+ peixiu: ["ol_peixiu", "peixiu"],
};
export default characterReplaces;
diff --git a/character/mobile/intro.js b/character/mobile/intro.js
index 95f177ca8..31df82376 100644
--- a/character/mobile/intro.js
+++ b/character/mobile/intro.js
@@ -18,7 +18,7 @@ const characterIntro = {
wangjun: "王濬(207年~286年),字士治,小名阿童,弘农郡湖县(今河南省灵宝市阌乡)人。西晋时期名将。王濬出身世家,博学多闻,容颜英俊,多谋善战。举秀才出身,起家河东郡从事。泰始八年(272年),担任广汉太守,平定益州叛乱,迁益州刺史。利用长江上游地势之利,修造战船,组建强大的水军。上书晋武帝,促成晋灭吴之战。咸宁六年(280年),率兵顺流而下,熔毁横江铁链,攻克丹阳郡,率先攻取石头城,接受吴末帝孙皓投降,完成西晋统一大业。凭借功勋,拜辅国将军、步兵校尉,册封襄阳侯。为避猜忌,纵情享受,累迁特进、抚军大将军、开府仪同三司、散骑常侍、后军将军等。太康六年十二月(286年1月18日),王濬去世,享年八十岁,谥号为“武”,安葬于柏谷山。",
yangfu: "杨阜(172年—244年),字义山,汉天水冀县(今甘谷县东南)人。三国时期曹魏名臣。汉献帝建安初年,任凉州从事,旋拜安定长史;韦康任刺史后辟为别驾,改任州参军;后因讨马超有功,赐爵关内侯。曹操征汉中时,杨阜担任益州刺史,回来后又担任武都太守。魏明帝时,由将作大匠改少府。杨阜不但卓识远见,而且刚正不阿,敢于直言,对朝廷弊政多有诤谏,六次进言谏魏明帝应勤政爱民,魏明帝对他颇有敬畏之心。杨阜勤政廉洁,在宫内担任少府时,专管宝器、珍膳、衣物等,而他死后则家无馀财。皇帝让杨阜的孙子杨豹继任了少府之职。原甘谷县文昌宫西侧有杨氏家祠,内悬“两代尚书”匾额。",
ruanhui: "阮氏女,是指三国时期曹魏名士许允之妻阮氏,陈留尉氏人。阮氏女是中国古代四大丑女之一,貌丑而见识非凡。她出身士族之家,是卫尉阮共(字伯彦)之女、阮侃(字德如)之妹。嫁与许允后生有二子:许奇,官至司隶校尉;许猛,官至幽州刺史。",
- peixiu: "裴秀(224年-271年4月3日),字季彦。河东郡闻喜县(今山西省闻喜县)人。[1]魏晋时期名臣、地图学家,东汉尚书令裴茂之孙、曹魏光禄大夫裴潜之子。出身河东裴氏,少年时便颇有名气,后被大将军曹爽辟为掾属,袭爵清阳亭侯,又迁黄门侍郎。高平陵之变后,因是曹爽的故吏而被罢免。此后历任廷尉正、安东将军及卫将军司马,参与谋划军国之政,参与平定诸葛诞叛乱。因功转任尚书,进封鲁阳乡侯。魏元帝继位后,进爵鲁阳县侯,任尚书仆射。咸熙元年(264年),受命负责修改官制,又提议恢复五等爵制。五等制恢复后,获封济川侯。他建议立司马炎为世子,司马炎继位晋王后,拜裴秀为尚书令、右光禄大夫。西晋建立后,加左光禄大夫,封钜鹿郡公。泰始三年(267年),升任司空。泰始七年(271年),裴秀因服食寒食散后饮冷酒而逝世,年四十八,谥号“元”。有文集三卷。裴秀作《禹贡地域图》,开创了中国古代地图绘制学。李约瑟称他为“中国科学制图学之父”,与古希腊著名地图学家托勒密齐名,是世界古代地图学史上东西辉映的两颗灿烂明星。为纪念这位中国地图科学创始人而设立的“裴秀奖”,每两年评选一次,是中国地图学界最高奖项。由于他的贡献突出,联合国天文组织将月球正面的一个环形山命名为“裴秀环形山”,",
+ peixiu: "裴秀(224年-271年4月3日),字季彦。河东郡闻喜县(今山西省闻喜县)人。魏晋时期名臣、地图学家,东汉尚书令裴茂之孙、曹魏光禄大夫裴潜之子。出身河东裴氏,少年时便颇有名气,后被大将军曹爽辟为掾属,袭爵清阳亭侯,又迁黄门侍郎。高平陵之变后,因是曹爽的故吏而被罢免。此后历任廷尉正、安东将军及卫将军司马,参与谋划军国之政,参与平定诸葛诞叛乱。因功转任尚书,进封鲁阳乡侯。魏元帝继位后,进爵鲁阳县侯,任尚书仆射。咸熙元年(264年),受命负责修改官制,又提议恢复五等爵制。五等制恢复后,获封济川侯。他建议立司马炎为世子,司马炎继位晋王后,拜裴秀为尚书令、右光禄大夫。西晋建立后,加左光禄大夫,封钜鹿郡公。泰始三年(267年),升任司空。泰始七年(271年),裴秀因服食寒食散后饮冷酒而逝世,年四十八,谥号“元”。有文集三卷。裴秀作《禹贡地域图》,开创了中国古代地图绘制学。李约瑟称他为“中国科学制图学之父”,与古希腊著名地图学家托勒密齐名,是世界古代地图学史上东西辉映的两颗灿烂明星。为纪念这位中国地图科学创始人而设立的“裴秀奖”,每两年评选一次,是中国地图学界最高奖项。由于他的贡献突出,联合国天文组织将月球正面的一个环形山命名为“裴秀环形山”。",
liucheng: "游卡桌游的原创人物。设定为黄忠的妻子。",
jiangwan: "蒋琬(?-246年),字公琰。零陵郡湘乡县人。三国时期蜀汉政治家,与诸葛亮、董允、费祎合称“蜀汉四相”。蒋琬最初随刘备入蜀,为广都县长。因其不理政事,惹怒刘备,在诸葛亮的劝说下才免于一死。后重获启用,受到诸葛亮的悉心培养,累官丞相长史兼抚军将军。建兴十二年(234年),诸葛亮去世,蒋琬继其执政,拜尚书令,又加行都护、假节,领益州刺史,再迁大将军,录尚书事,封安阳亭侯。延熙元年(238年),受命开府,加大司马,总揽蜀汉军政。曾制定由水路进攻曹魏的计划,但未被采纳。延熙九年(246年),蒋琬病逝,谥号为恭。",
sunhanhua: "孙寒华,三国时女仙。梁·陶弘景《真诰》卷一三、五代·杜光庭《墉城集仙录》卷七:其父孙贲为孙权堂兄,寒华少时与杜契有私情,后从杜契受玄白之要,颜容日少。周旋吴越诸山十馀年,得道仙去。《鉴后集》卷四:一云即吴大帝孙权之女。于茅山修道,道成,冲虚而去,因号其山为华姥山。山在茅山崇禧观前。《神异典》卷二五九人于明代,误。",
diff --git a/character/mobile/skill.js b/character/mobile/skill.js
index 235f6558a..04170494f 100644
--- a/character/mobile/skill.js
+++ b/character/mobile/skill.js
@@ -119,6 +119,9 @@ const skills = {
if (cards.length) await player.discard(cards);
await player.draw(4);
},
+ ai: {
+ combo: "mbpanxiang"
+ },
},
//李昭焦伯
mbzuoyou: {
@@ -933,7 +936,7 @@ const skills = {
return true;
},
zhuanhuanji2(skill, player) {
- return player.countMark("mbxuetu_status") !== 1;
+ return player && player.countMark("mbxuetu_status") !== 1;
},
position: "he",
onremove: ["mbxuetu", "mbxuetu_status"],
@@ -1376,6 +1379,9 @@ const skills = {
async content(event, trigger, player) {
trigger.num++;
},
+ ai: {
+ combo: "zhoulin"
+ },
},
zhoulin: {
audio: 2,
@@ -4046,7 +4052,6 @@ const skills = {
},
ai: {
threaten: 2.5,
- halfneg: true,
},
subSkill: {
block: {
@@ -7086,38 +7091,46 @@ const skills = {
bingqing: {
audio: 2,
trigger: { player: "useCardAfter" },
- direct: true,
- filter: function (event, player) {
- var suit = get.suit(event.card);
+ filter(event, player) {
+ const evt = event.getParent("phaseUse");
+ if (!evt || !evt.player || evt.player != player) return false;
+ const suit = get.suit(event.card);
if (!lib.suit.includes(suit)) return false;
- var evt = event.getParent("phaseUse");
- if (!evt || player != evt.player) return false;
- var list = [],
- history = player.getHistory("useCard");
- if (history.length < 2) return false;
- for (var i of history) {
- if (i.getParent("phaseUse") != evt) continue;
- var suit2 = get.suit(i.card);
- if (!lib.suit.includes(suit2)) continue;
- if (i != event && suit2 == suit) return false;
- if (i.finished) list.add(suit2);
- }
- return list.length > 1 && list.length < 5;
+ if (
+ player
+ .getHistory("useCard", evtx => {
+ return evtx.getParent("phaseUse") == evt && get.suit(evtx.card) == suit;
+ })
+ .indexOf(event) != 0
+ )
+ return false;
+ return Array.from({ length: 3 })
+ .map((_, i) => i + 2)
+ .includes(
+ player
+ .getHistory(
+ "useCard",
+ evtx => {
+ return evtx.getParent("phaseUse") == evt && lib.suit.includes(get.suit(evtx.card));
+ },
+ event
+ )
+ .reduce((list, evtx) => list.add(get.suit(evtx.card)), []).length
+ );
},
- content: function () {
- "step 0";
- var suit = get.suit(trigger.card);
- var evt = event.getParent("phaseUse");
- var list = [],
- history = player.getHistory("useCard");
- for (var i of history) {
- if (i.getParent("phaseUse") != evt) continue;
- var suit2 = get.suit(i.card);
- if (!lib.suit.includes(suit2)) continue;
- if (i.finished) list.add(suit2);
- }
- var prompt, filterTarget, ai;
- switch (list.length) {
+ async cost(event, trigger, player) {
+ const evt = trigger.getParent("phaseUse");
+ const num = player
+ .getHistory(
+ "useCard",
+ evtx => {
+ return evtx.getParent("phaseUse") == evt && lib.suit.includes(get.suit(evtx.card));
+ },
+ trigger
+ )
+ .reduce((list, evtx) => list.add(get.suit(evtx.card)), []).length;
+ let prompt, filterTarget, ai;
+ switch (num) {
case 2:
prompt = "令一名角色摸两张牌";
filterTarget = function (card, player, target) {
@@ -7139,7 +7152,7 @@ const skills = {
};
ai = function (target) {
var player = _status.event.player;
- return get.effect(target, { name: "guohe_copy" }, player, player);
+ return get.effect(target, { name: "guohe" }, player, player);
};
break;
case 4:
@@ -7153,29 +7166,30 @@ const skills = {
};
break;
default:
- event.finish();
+ event.result = { bool: false };
return;
}
- event.num = list.length;
- player.chooseTarget(get.prompt("bingqing"), prompt, filterTarget).set("ai", ai);
- "step 1";
- if (result.bool) {
- var target = result.targets[0];
- player.logSkill("bingqing", target);
- event.target = target;
- event.goto(num);
- } else event.finish();
- "step 2";
- target.draw(2);
- event.finish();
- "step 3";
- player.discardPlayerCard(target, true, "hej");
- event.finish();
- "step 4";
- target.damage();
+ let result = await player.chooseTarget(get.prompt("bingqing"), prompt, filterTarget).set("ai", ai).forResult();
+ result.cost_data = num;
+ event.result = result;
+ },
+ async content(event, trigger, player) {
+ const target = event.targets[0];
+ switch (event.cost_data) {
+ case 2:
+ await target.draw(2);
+ break;
+ case 3:
+ await player.discardPlayerCard(target, true, "hej");
+ break;
+ case 4:
+ await target.damage();
+ break;
+ }
},
},
yingfeng: {
+ audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
direct: true,
content: function () {
@@ -8385,62 +8399,6 @@ const skills = {
}
},
},
- //新华歆
- yuanqing: {
- audio: 2,
- trigger: { player: "phaseUseEnd" },
- forced: true,
- filter: function (event, player) {
- return player.hasHistory("useCard", function (evt) {
- return evt.getParent("phaseUse") == event;
- });
- },
- content: function () {
- var map = {},
- cards = [];
- player.getHistory("useCard", function (evt) {
- if (evt.getParent("phaseUse") == trigger) {
- var type = get.type2(evt.card, false);
- if (!map[type]) map[type] = [];
- }
- });
- for (var i = 0; i < ui.discardPile.childNodes.length; i++) {
- var card = ui.discardPile.childNodes[i],
- type = get.type2(card, false);
- if (map[type]) map[type].push(card);
- }
- for (var i in map) {
- if (map[i].length) cards.push(map[i].randomGet());
- }
- if (cards.length) {
- player.$gain2(cards, false);
- game.cardsGotoSpecial(cards, "toRenku");
- game.log(player, "将", cards, "置入了仁库");
- game.delayx();
- }
- },
- init: function (player) {
- player.storage.renku = true;
- },
- },
- shuchen: {
- audio: 2,
- init: function (player) {
- player.storage.renku = true;
- },
- trigger: { global: "dying" },
- forced: true,
- filter: function (event, player) {
- return _status.renku.length > 3;
- },
- logTarget: "player",
- content: function () {
- player.gain(_status.renku, "gain2", "fromRenku");
- _status.renku.length = 0;
- game.updateRenku();
- trigger.player.recover();
- },
- },
//谯周
zhiming: {
audio: 2,
@@ -8488,16 +8446,11 @@ const skills = {
xingbu: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
- prompt2: "亮出牌堆顶的三张牌,并可以根据其中红色牌的数量,令一名其他角色获得一种效果",
+ prompt2: "展示牌堆顶的三张牌,并可以根据其中红色牌的数量,令一名其他角色获得一种效果",
content: function () {
"step 0";
- var cards = get.cards(3);
- //for(var i=cards.length-1;i--;i>=0){
- // ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild);
- //}
- game.updateRoundNumber();
+ var cards = get.cards(3, true);
event.cards = cards;
- //game.cardsGotoOrdering(cards);
player.showCards(cards, get.translation(player) + "发动了【星卜】");
"step 1";
var num = 0;
@@ -11577,7 +11530,10 @@ const skills = {
trigger: { player: "phaseBegin" },
forced: true,
audio: "dangxian",
- audioname: ["guansuo", "xin_liaohua"],
+ audioname: ["xin_liaohua"],
+ audioname2: {
+ guansuo: "dangxian_guansuo",
+ },
content: function () {
"step 0";
var card = get.discardPile(function (card) {
@@ -16127,7 +16083,7 @@ const skills = {
player.draw(event.num);
},
ai: {
- halfneg: true,
+ neg: true,
},
},
yixiang: {
diff --git a/character/mobile/translate.js b/character/mobile/translate.js
index d6e54587e..89461bb75 100644
--- a/character/mobile/translate.js
+++ b/character/mobile/translate.js
@@ -32,7 +32,7 @@ const translates = {
kuangcai: "狂才",
kuangcai_info: "出牌阶段开始时,你可以令你此阶段内的主动出牌时间变为5秒。若如此做,你于此阶段内使用牌没距离和次数限制,且每当你于此阶段内使用牌时,你摸一张牌且主动出牌时间-1秒。若主动出牌时间减至0,则你结束出牌阶段。",
shejian: "舌剑",
- shejian_info: "弃牌阶段结束时,若你于此阶段弃置的所有牌花色均不相同,则你可以弃置一名其他角色的一张牌。",
+ shejian_info: "弃牌阶段结束时,若你于此阶段弃置过至少两张牌且这些牌花色均不相同,则你可以弃置一名其他角色的一张牌。",
xinfu_daigong: "怠攻",
xinfu_daigong_info: "每回合限一次。当你受到伤害时,你可以展示所有手牌,然后令伤害来源选择一项:交给你一张与你所有手牌花色均不相同的一张牌,或防止此伤害。",
xinfu_zhaoxin: "昭心",
@@ -360,8 +360,7 @@ const translates = {
requanfeng_info: "限定技。①其他角色死亡时,你可失去〖弘仪〗,然后获得其武将牌上的所有非主公技,非隐匿技和非Charlotte技,加1点体力上限并回复1点体力。②当你处于濒死状态时,你可以加2点体力上限,然后回复4点体力。",
quanfeng: "劝封",
quanfeng_info: "锁定技,限定技,一名角色死亡时,你选择获得其的一个技能(主公技,限定技,觉醒技,隐匿技,使命技,带有Charlotte标签的技能除外),然后加1点体力上限并回复1点体力。",
- simashi: "手杀司马师",
- simashi_prefix: "手杀",
+ simashi: "司马师",
baiyi: "败移",
baiyi_info: "限定技,出牌阶段,若你已受伤,你可以交换两名其他角色的座次。",
jinglve: "景略",
@@ -479,7 +478,7 @@ const translates = {
zhiming: "知命",
zhiming_info: "准备阶段开始时或弃牌阶段结束时,你摸一张牌,然后可以将一张牌置于牌堆顶。",
xingbu: "星卜",
- xingbu_info: "结束阶段,你可以亮出牌堆顶的三张牌,然后你可以根据X值(X为这三张牌中红色牌的数量),令一名其他角色获得对应的效果直到其下回合结束:①三张:其摸牌阶段多摸两张牌,使用【杀】的次数上限+1。②两张:其使用【杀】的次数上限-1,跳过弃牌阶段。③小于两张:其于准备阶段开始时弃置一张手牌。",
+ xingbu_info: "结束阶段,你可以展示牌堆顶的三张牌,然后你可以根据X值(X为这三张牌中红色牌的数量),令一名其他角色获得对应的效果直到其下回合结束:①三张:其摸牌阶段多摸两张牌,使用【杀】的次数上限+1。②两张:其使用【杀】的次数上限-1,跳过弃牌阶段。③小于两张:其于准备阶段开始时弃置一张手牌。",
xin_sunluban: "手杀界孙鲁班",
xin_sunluban_prefix: "手杀界",
xinzenhui: "谮毁",
@@ -542,7 +541,7 @@ const translates = {
spqishe_info: "你可以将一张装备牌当做【酒】使用。你的手牌上限+X(X为你装备区内的牌数)。",
sp_maojie: "毛玠",
bingqing: "秉清",
- bingqing_info: "当你于出牌阶段内使用的牌结算结束后,若你于本阶段内使用的所有已结算结束的其他牌与此牌花色均不相同,则你可根据X的值执行对应效果:为2,你令一名角色摸两张牌;为3,你弃置一名角色区域内的一张牌;为4,你对一名其他角色造成1点伤害。(X为你本阶段内使用过的已结算结束的牌中包含的花色数)",
+ bingqing_info: "当你于出牌阶段内使用的牌结算完毕后,若你于本阶段内此前使用的所有牌的花色与此牌花色均不相同,则你可根据X的值执行对应效果:为2,你令一名角色摸两张牌;为3,你弃置一名角色区域内的一张牌;为4,你对一名其他角色造成1点伤害。(X为你于本阶段内此前使用的所有牌包含的花色数+1)",
yingfeng: "迎奉",
yingfeng_info: "准备阶段,你可以令一名角色获得“奉”标记并移除场上所有其他的“奉”标记。有“奉”标记的角色使用牌没有距离限制。",
xin_sunxiu: "手杀界孙休",
@@ -563,7 +562,8 @@ const translates = {
miheng_prefix: "手杀",
re_gaoshun: "手杀界高顺",
re_gaoshun_prefix: "手杀界",
- peixiu: "裴秀",
+ peixiu: "手杀裴秀",
+ peixiu_prefix: "手杀",
xingtu: "行图",
xingtu1: "倍数",
xingtu2: "约数",
@@ -786,8 +786,7 @@ const translates = {
mutao_info: "出牌阶段限一次。你可以选择一名角色,令其将手牌中所有的【杀】置于武将牌上,然后将这些牌依次随机交给其下家开始的每一名角色。然后其对最后一名以此法获得【杀】的角色A造成X点伤害(X为A手牌中【杀】的数量且至多为2)。",
yimou: "毅谋",
yimou_info: "当一名角色受到伤害后,若其存活且你至其的距离不大于1,你可以选择一项:1.令其从牌堆中获得一张【杀】;2.令其将一张手牌交给另一名角色,然后摸一张牌。",
- jiangji: "手杀蒋济",
- jiangji_prefix: "手杀",
+ jiangji: "蒋济",
jilun: "机论",
jilun_info: "①当你受到伤害后,若你拥有技能〖急筹〗,则你可以一项:1.摸两张牌。2.获得1枚“机论”标记。②一名角色的结束阶段,若你拥有“机论”,则重复选择执行以下项直到你没有“机论”标记:1.失去1枚“机论”标记,视为使用一张〖急筹①〗记录过且未被〖机论②〗记录过的普通锦囊牌并记录此牌牌名。2.失去所有“机论”标记。",
liwei: "李遗",
diff --git a/character/offline/character.js b/character/offline/character.js
index bef9d0355..b41fe4f88 100644
--- a/character/offline/character.js
+++ b/character/offline/character.js
@@ -1,4 +1,5 @@
const characters = {
+ yj_ehuan: ["male", "qun", 4, ["psdiwan", "pssuiluan", "psconghan"], ["doublegroup:shu:qun"]],
yj_zhouji: ["female", "wu", 3, ["psyanmou", "pszhanyan", "psyuhuo"]],
drag_guanyu: ["male", "shu", 4, ["dragchaojue", "dragjunshen"]],
drag_caoren: ["male", "wei", 4, ["draglizhong", "dragjuesui"]],
diff --git a/character/offline/intro.js b/character/offline/intro.js
index a5ad13fa2..b754e5e77 100644
--- a/character/offline/intro.js
+++ b/character/offline/intro.js
@@ -1,4 +1,5 @@
const characterIntro = {
+ ehuan: "鄂焕,古典文学名著《三国演义》人物,为蜀将高定部将,身长九尺,面目狰狞,使一只方天戟,有万夫不当之勇。于孔明征朱褒、雍闿时粉墨登场,与魏延大战不分胜负,后中计被魏延、王平、张翼联手擒获,孔明以礼相待,成功离间高定与朱、雍二人。后高定派鄂焕斩朱褒、平雍闿,二人一起归蜀,鄂焕遂因其功而被封为牙门将。",
zhouji: "三国杀集换式卡牌游戏《阵面对决》中的权倾系列卡牌。游卡桌游官方的三国时期女性角色,原型是周妃(又名周彻)。周瑜之女。",
lvchang: "吕常(161—221年),荆州南阳博望(今河南省南阳市方城县博望镇)人,汉末至三国时期曹魏将领。吕常曾担任曹魏横海将军、章陵太守,为武猛都尉厉节中郎将裨将军,封关内侯。常以中勇,显名州司,试守雉长,执戈秉戎,慎守易,兵不顿于敌国,坠不侵于四邻,拜武猛都尉厉节中郎将裨将军,封关内侯。王师南征,与充军从,奄有江汉,舍爵册勋,封阴德亭侯,领郡。鸠集荒散,为民统纪,三考有成,转拜平狄将军,改封卢亭侯,莅国赋政,十有三年。会蜀将关羽猖獗为寇,常御之,羽不能克。文帝加其庸,转拜横海将军,徙封西鄂都乡侯,食邑并七百户。年六十一,黄初二年正月卒。",
huangjinleishi: "黄巾军中负责施法的女祭司二人组。",
diff --git a/character/offline/skill.js b/character/offline/skill.js
index 5a9080185..2b4b8d2be 100644
--- a/character/offline/skill.js
+++ b/character/offline/skill.js
@@ -2,13 +2,120 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
- //线下E系列肘击
+ //线下E系列
+ //鄂焕
+ psdiwan: {
+ trigger: { player: "useCardToPlayered" },
+ filter(event, player) {
+ return event.card.name == "sha" && event.isFirstTarget;
+ },
+ frequent: true,
+ usable: 1,
+ content() {
+ player.draw(trigger.targets.length);
+ },
+ },
+ pssuiluan: {
+ trigger: { player: "useCard2" },
+ filter(event, player) {
+ if (player.group != "qun" || event.card.name != "sha") return false;
+ return (
+ game.countPlayer(target => {
+ return !event.targets.includes(target) && lib.filter.targetEnabled2(event.card, player, target) && lib.filter.targetInRange(event.card, player, target);
+ }) > 1
+ );
+ },
+ groupSkill: true,
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(
+ get.prompt2("pssuiluan"),
+ (card, player, target) => {
+ const event = get.event().getTrigger();
+ return !event.targets.includes(target) && lib.filter.targetEnabled2(event.card, player, target) && lib.filter.targetInRange(event.card, player, target);
+ },
+ 2
+ )
+ .set("ai", target => {
+ const player = get.event("player"),
+ event = get.event().getTrigger();
+ return get.effect(target, event.card, player);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.targets.addArray(event.targets);
+ player.addTempSkill("pssuiluan_effect");
+ trigger.card.pssuiluan = true;
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ trigger: { player: ["useCardAfter", "damageEnd"] },
+ filter(event, player) {
+ if (event.name == "damage") {
+ return player.group != "shu" && event.getParent(4).name == "pssuiluan_effect";
+ }
+ return event.card.pssuiluan && (event.targets || []).some(i => i.isIn());
+ },
+ forced: true,
+ popup: false,
+ forceDie: true,
+ async content(event, trigger, player) {
+ if (trigger.name == "damage") {
+ await player.changeGroup("shu");
+ return;
+ }
+ const targets = trigger.targets.filter(i => i.isIn()).sortBySeat();
+ for (const target of targets) {
+ await target
+ .chooseToUse(function (card, player, event) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.filterCard.apply(this, arguments);
+ }, "随乱:是否对" + get.translation(player) + "使用一张【杀】?")
+ .set("filterTarget", function (card, player, target) {
+ if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
+ return lib.filter.filterTarget.apply(this, arguments);
+ })
+ .set("targetRequired", true)
+ .set("complexSelect", true)
+ .set("sourcex", player);
+ }
+ },
+ },
+ },
+ },
+ psconghan: {
+ trigger: { global: "damageSource" },
+ filter(event, player) {
+ if (player.group != "shu" || !event.source || !event.player.isIn()) return false;
+ return event.source.getSeatNum() == 1 && (player.hasSha() || (_status.connectMode && player.countCards("hs")));
+ },
+ direct: true,
+ groupSkill: true,
+ content() {
+ player
+ .chooseToUse(function (card, player, event) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.filterCard.apply(this, arguments);
+ }, get.prompt2("psconghan", trigger.player))
+ .set("filterTarget", function (card, player, target) {
+ if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
+ return lib.filter.filterTarget.apply(this, arguments);
+ })
+ .set("targetRequired", true)
+ .set("complexSelect", true)
+ .set("logSkill", ["psconghan", trigger.player])
+ .set("sourcex", trigger.player);
+ },
+ },
+ //肘击
psyanmou: {
getCards(event, player) {
let cards = [];
if (event.name == "cardsDiscard") {
const evt = event.getParent().relatedEvent;
- if (evt && evt.name == "judge" && evt.player == player) {
+ if (evt && evt.name == "judge" && evt.player != player) {
cards.addArray(event.cards.filter(i => get.position(i, true) == "d"));
}
} else {
@@ -738,8 +845,6 @@ const skills = {
var go = false,
d1 = false;
if (get.attitude(player, trigger.player) > 0) {
- d1 = true;
- if (trigger.player.hasSkill("jueqing") || trigger.player.hasSkill("gangzhi")) d1 = false;
for (var target of trigger.targets) {
if (
!target.mayHaveShan(
@@ -759,15 +864,17 @@ const skills = {
true
)
) {
- if (!target.hasSkill("gangzhi")) d1 = false;
if (
- target.hasSkillTag("filterDamage", null, {
+ get.attitude(player, target) < 0 &&
+ !trigger.player.hasSkillTag("jueqing", false, target) &&
+ !target.hasSkillTag("filterDamage", null, {
player: trigger.player,
card: trigger.card,
- }) ||
- get.attitude(player, target) >= 0
- )
- d1 = false;
+ })
+ ) {
+ d1 = true;
+ break;
+ }
}
}
if (trigger.addCount === false || !trigger.player.isPhaseUsing()) go = false;
@@ -4267,61 +4374,46 @@ const skills = {
intro: {
content: "limited",
},
- direct: true,
- content: function () {
- "step 0";
- player
- .chooseTarget(get.prompt2("yjyongdi"), function (card, player, target) {
- return target.hasSex("male") || target.name == "key_yuri";
- })
- .set("ai", function (target) {
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(
+ get.prompt2("yjyongdi"),
+ (card, player, target) => {
+ return target.hasSex("male") || target.name == "key_yuri";
+ }
+ )
+ .set("ai", target => {
if (!_status.event.goon) return 0;
var player = _status.event.player;
var att = get.attitude(player, target);
if (att <= 1) return 0;
var mode = get.mode();
if (mode == "identity" || (mode == "versus" && _status.mode == "four")) {
- if (target.name && lib.character[target.name]) {
- for (var i = 0; i < lib.character[target.name][3].length; i++) {
- if (lib.skill[lib.character[target.name][3][i]].zhuSkill) {
- return att * 2;
- }
- }
- }
+ if (target.getStockSkills(true, true).some(i => {
+ if (target.hasSkill(i)) return false;
+ let info = get.info(i);
+ return info && info.zhuSkill;
+ })) return att * 2;
}
return att;
})
- .set("goon", !player.hasUnknown());
- "step 1";
- if (result.bool) {
- player.awakenSkill("yjyongdi");
- player.logSkill("yjyongdi", result.targets);
- var target = result.targets[0];
- target.gainMaxHp(true);
- target.recover();
- var mode = get.mode();
- if (mode == "identity" || (mode == "versus" && _status.mode == "four") || mode == "doudizhu") {
- if (target.name && lib.character[target.name]) {
- var skills = lib.character[target.name][3];
- target.storage.zhuSkill_yjyongdi = [];
- for (var i = 0; i < skills.length; i++) {
- var info = lib.skill[skills[i]];
- if (info.zhuSkill) {
- target.storage.zhuSkill_yjyongdi.push(skills[i]);
- if (info.init) {
- info.init(target);
- }
- if (info.init2) {
- info.init2(target);
- }
- }
- }
- }
- }
- }
+ .set("goon", !player.hasUnknown())
+ .forResult();
},
- ai: {
- expose: 0.2,
+ async content(event, trigger, player) {
+ player.awakenSkill("yjyongdi");
+ let target = event.targets[0], mode = get.mode();
+ if (player !== target && (mode !== "identity" || player.identity !== "nei")) player.addExpose(0.3);
+ target.gainMaxHp(true);
+ target.recover();
+ if (mode == "identity" || (mode == "versus" && _status.mode == "four") || mode == "doudizhu") {
+ let skills = target.getStockSkills(true, true).filter(i => {
+ if (target.hasSkill(i)) return false;
+ let info = get.info(i);
+ return info && info.zhuSkill;
+ });
+ if (skills.length) target.addSkills(skills);
+ }
},
},
//用间篇豪华版盒子许攸
@@ -4930,6 +5022,9 @@ const skills = {
player.gift(result.cards, target);
}
},
+ ai: {
+ combo: "yixiandao"
+ },
},
yjyibing: {
trigger: {
@@ -5485,7 +5580,7 @@ const skills = {
if (event.lose && event.lose.loseHp) player.draw();
},
ai: {
- halfneg: true,
+ neg: true,
filterDamage: true,
skillTagFilter: function (player, tag, arg) {
if (tag === "filterDamage" && arg && arg.player) {
diff --git a/character/offline/sort.js b/character/offline/sort.js
index 850350669..896c3fa61 100644
--- a/character/offline/sort.js
+++ b/character/offline/sort.js
@@ -5,7 +5,7 @@ const characterSort = {
offline_luanwu: ["ns_lijue", "ns_zhangji", "ns_fanchou"],
offline_yongjian: ["ns_chendao", "yj_caoang", "yj_caocao", "yj_liru", "yj_caohong", "yj_zhangfei", "yongjian_ganning", "yj_dongzhuo", "yj_xuyou", "yj_jiaxu", "yj_zhenji"],
offline_piracyE_zy: ["shen_jiaxu", "pe_wangyun", "pe_zhonghui", "pe_sunchen", "pe_mengda", "pe_wenqin", "ns_caoanmin", "jiangqing", "kongrong", "jiling", "tianfeng", "mateng"],
- offline_piracyE: ["yj_zhouji"],
+ offline_piracyE: ["yj_zhouji", "yj_ehuan"],
offline_piracyS: ["ns_jiaxu", "longyufei", "ps_guanyu", "ps1059_guojia", "ps2070_guojia", "ps2063_zhaoyun", "ps2067_zhaoyun", "ps1062_zhouyu", "ps2080_zhouyu", "ps_caozhi", "ps_jin_simayi", "ps_caopi", "ps_simayi", "ps2068_simayi", "ps_machao", "ps_zhugeliang", "ps2066_zhugeliang", "ps_jiaxu", "ps_lvbu", "ps_shen_machao", "jsp_liubei"],
offline_piracyK: ["pk_sp_duyu"],
offline_vtuber: ["vtb_xiaosha", "vtb_xiaoshan", "vtb_xiaotao", "vtb_xiaole", "vtb_xiaojiu"],
diff --git a/character/offline/translate.js b/character/offline/translate.js
index cf2711af4..44baa2304 100644
--- a/character/offline/translate.js
+++ b/character/offline/translate.js
@@ -404,8 +404,7 @@ const translates = {
drag_guanyu_prefix: "龙",
drag_caoren: "龙曹仁",
drag_caoren_prefix: "龙",
- drag_lvchang: "龙吕常",
- drag_lvchang_prefix: "龙",
+ drag_lvchang: "吕常",
dragchaojue: "超绝",
dragchaojue_info: "准备阶段,你可以弃置一张手牌,然后令所有其他角色本回合不能使用或打出此花色的牌,然后这些角色依次选择一项:①正面朝上交给你一张牌;②本回合非锁定技失效。",
dragjunshen: "军神",
@@ -425,6 +424,13 @@ const translates = {
pszhanyan_info: "出牌阶段限一次,你可以令你攻击范围内的所有角色依次选择一项:①受到你对其造成的1点火属性伤害;②将手牌或弃牌堆中的一张【火攻】或火【杀】置于牌堆顶。然后你摸X张牌(X为本次选择次数较小的选项的被选择次数)。",
psyuhuo: "驭火",
psyuhuo_info: "锁定技。①防止你受到的火属性伤害。②你的【火攻】和火【杀】不计入手牌上限。",
+ yj_ehuan: "鄂焕",
+ psdiwan: "敌万",
+ psdiwan_info: "每回合限一次,当你使用【杀】指定第一个目标后,你可以摸X张牌(X为此牌指定的目标数)。",
+ pssuiluan: "随乱",
+ pssuiluan_info: "群势力技。你使用【杀】可以额外指定两个目标,若如此做,此牌结算完毕后,所有目标角色可依次对你使用一张【杀】,你以此法受到伤害后,将势力变更至蜀。",
+ psconghan: "从汉",
+ psconghan_info: "蜀势力技。一号位造成伤害后,你可以对受伤角色使用一张【杀】。",
};
export default translates;
diff --git a/character/old/voices.js b/character/old/voices.js
index 415905f3a..0df0c32fa 100644
--- a/character/old/voices.js
+++ b/character/old/voices.js
@@ -1,3 +1,6 @@
export default {
- "#huangzhong:die": "不得不服老啦~",
+ "#old_fuhun1": "呐喊破敌,锐不可挡!",
+ "#old_fuhun2": "匹夫之勇,插标卖首!",
+ "#old_guanzhang:die": "父亲,我来了……",
+ "#huangzhong:die": "不得不服老啦~",
};
diff --git a/character/onlyOL/skill.js b/character/onlyOL/skill.js
index 3f56be324..8072f0f20 100644
--- a/character/onlyOL/skill.js
+++ b/character/onlyOL/skill.js
@@ -313,7 +313,7 @@ const skills = {
.chooseToUse(function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
- }, "眩惑:对" + get.translation(player) + "使用一张【杀】,或令" + get.translation(player) + "你的手牌并获得你的两张牌")
+ }, "眩惑:对" + get.translation(target2) + "使用一张【杀】,或令" + get.translation(player) + "你的手牌并获得你的两张牌")
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.targetEnabled.apply(this, arguments);
@@ -383,7 +383,7 @@ const skills = {
if (goon && player.isDamaged())
result = await player
.chooseControl()
- .set("choiceList", ["获得" + get.translation(target) + "的一张牌", "发动一次〖秘计〗"])
+ .set("choiceList", ["获得" + get.translation(target) + "的一张牌", "于本回合的结束阶段发动一次〖秘计〗"])
.set("ai", () => {
const player = get.event("player"),
target = get.event().getTrigger().player;
@@ -394,16 +394,28 @@ const skills = {
if (result.index == 0) {
await player.gainPlayerCard(target, "he", true);
} else {
- await player.useSkill("olmiji");
+ player.addTempSkill("olzhenlie_effect");
+ player.addMark("olzhenlie_effect", 1, false);
}
}
},
+ subSkill: {
+ effect: {
+ charlotte: true,
+ onremove: true,
+ intro: { content: "本回合的结束阶段可以发动#次〖秘计〗" },
+ },
+ },
},
olmiji: {
audio: 2,
- trigger: { player: "phaseJieshuBegin" },
+ trigger: { global: "phaseJieshuBegin" },
filter(event, player) {
- return player.isDamaged();
+ if (player.isHealthy()) return false;
+ return event.player == player || player.hasMark("olzhenlie_effect");
+ },
+ getIndex(event, player) {
+ return player.countMark("olzhenlie_effect") + (event.player == player);
},
async content(event, trigger, player) {
let num = player.getDamagedHp();
@@ -857,7 +869,7 @@ const skills = {
true
)
) {
- if (player.hasSkill("jueqing") || target.hasSkill("gangzhi")) extra_num--;
+ if (player.hasSkillTag("jueqing", false, target)) extra_num--;
else if (
target.hasSkillTag("filterDamage", null, {
player: event.player,
@@ -1037,7 +1049,6 @@ const skills = {
}
}
},
- ai: { combo: "olsbyufeng" },
},
//界高顺
olxianzhen: {
@@ -1712,8 +1723,10 @@ const skills = {
},
kunfenx: {
audio: "kunfen",
- audioname: ["ol_sb_jiangwei"],
+ audioname2: { ol_sb_jiangwei: "kunfen_ol_sb_jiangwei" },
},
+ kunfen_ol_sb_jiangwei: { audio: 1 },
+ zhaxiang_ol_sb_jiangwei: { audio: 1 },
//界曹彰
oljiangchi: {
audio: "rejiangchi",
diff --git a/character/onlyOL/translate.js b/character/onlyOL/translate.js
index 6f2e8763e..f5687865c 100644
--- a/character/onlyOL/translate.js
+++ b/character/onlyOL/translate.js
@@ -69,7 +69,7 @@ const translates = {
ol_wangyi: "OL界王异",
ol_wangyi_prefix: "OL界",
olzhenlie: "贞烈",
- olzhenlie_info: "当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后你选择一项:①获得使用者的一张牌;②发动一次〖秘计〗。",
+ olzhenlie_info: "当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后你选择一项:①获得使用者的一张牌;②于本回合的结束阶段发动一次〖秘计〗。",
olmiji: "秘计",
olmiji_info: "结束阶段,若你已受伤,则你可以摸X张牌,然后你可以将至多X张牌任意分配给其他角色(X为你已损失的体力值)。",
ol_sb_pangtong: "OL谋庞统",
@@ -78,14 +78,14 @@ const translates = {
olsbhongtu_info: "一名角色的阶段结束时,若你于此阶段得到过至少两张牌,你可以摸三张牌,展示三张手牌,令一名其他角色选择是否使用其中一张牌并令你随机弃置其中另一张牌。若使用牌的点数于三张牌中满足以下条件,其获得如下技能或效果直到其下一个回合的回合结束:唯一最大,其获得〖飞军〗;不为唯一最大且不为唯一最小,其获得〖潜袭〗;唯一最小,其手牌上限+2。若其未以此法使用牌,你对其与你各造成1点火焰伤害。",
olsbqiwu: "栖梧",
olsbqiwu_info: "当你每回合首次受到伤害时,若伤害来源为你或在你的攻击范围内,你可以弃置一张红色牌,防止此伤害。",
- ol_fazheng:'OL界法正',
- ol_fazheng_prefix:'OL界',
- olxuanhuo:'眩惑',
- olxuanhuo_info:'摸牌阶段结束时,你可以交给一名其他角色两张牌,然后其选择一项:1.对你选择的另一名其他角色使用一张【杀】,2.令你观看并获得其两张牌。',
- olenyuan:'恩怨',
- olenyuan1:'恩怨',
- olenyuan2:'恩怨',
- olenyuan_info:'①当你一次性获得一名其他角色超过一张牌后,你可以令其摸一张牌。②当你受到1点伤害后,你可以令伤害来源选择一项:1.将一张红色手牌交给你;2.失去1点体力。',
+ ol_fazheng: "OL界法正",
+ ol_fazheng_prefix: "OL界",
+ olxuanhuo: "眩惑",
+ olxuanhuo_info: "摸牌阶段结束时,你可以交给一名其他角色两张牌,然后其选择一项:1.对你选择的另一名其他角色使用一张【杀】,2.令你观看并获得其两张牌。",
+ olenyuan: "恩怨",
+ olenyuan1: "恩怨",
+ olenyuan2: "恩怨",
+ olenyuan_info: "①当你一次性获得一名其他角色超过一张牌后,你可以令其摸一张牌。②当你受到1点伤害后,你可以令伤害来源选择一项:1.将一张红色手牌交给你;2.失去1点体力。",
};
export default translates;
diff --git a/character/onlyOL/voices.js b/character/onlyOL/voices.js
index 5d3ba39fe..dca1b6852 100644
--- a/character/onlyOL/voices.js
+++ b/character/onlyOL/voices.js
@@ -3,6 +3,8 @@ export default {
"#olsbzhuri2": "知天命而不顺,履穷途而强为。",
"#olsbranji1": "此身为薪,炬成灰亦昭大汉长明!",
"#olsbranji2": "维之一腔骨血,可驱驰来北马否?",
+ "#kunfen_ol_sb_jiangwei1": "虽千万人,吾往矣!",
+ "#zhaxiang_ol_sb_jiangwei1": "亡国之将姜维,请明公驱驰。",
"#ol_sb_jiangwei:die": "姜维姜维……又将何为?",
"#xuanfeng_re_lingtong1": "短兵相接,让敌人丢盔弃甲!",
"#xuanfeng_re_lingtong2": "攻敌不备,看他们闻风而逃!",
diff --git a/character/rank.js b/character/rank.js
index ca698486f..4bec6a9c0 100644
--- a/character/rank.js
+++ b/character/rank.js
@@ -139,6 +139,7 @@ window.noname_character_rank = {
"dc_simashi",
"dc_sb_simayi",
"dc_sb_jiaxu",
+ "dc_sb_zhangxiu",
"caofang",
"dc_shen_huatuo",
"sp_zhenji",
@@ -147,6 +148,8 @@ window.noname_character_rank = {
"guanyue",
"wupu",
"xukun",
+ "ol_feiyi",
+ "ol_jiangwan",
],
a: [
"star_caoren",
@@ -285,6 +288,9 @@ window.noname_character_rank = {
"zhangqiying",
"wangyuanji",
"miheng",
+ "yue_miheng",
+ "chezhou",
+ "zhupeilan",
"re_guojia",
"re_sunquan",
"re_zhangjiao",
@@ -391,6 +397,9 @@ window.noname_character_rank = {
"yj_xuangongzhu",
"ol_sb_pangtong",
"dc_sb_zhugejin",
+ "matie",
+ "dc_sb_caoang",
+ "dc_sb_guanping",
],
am: [
"tw_yanliang",
@@ -712,8 +721,12 @@ window.noname_character_rank = {
"jsrg_yuanshao",
"sb_handang",
"sb_gongsunzan",
+ "yue_zoushi",
],
bp: [
+ "ol_peixiu",
+ "caimao",
+ "yj_ehuan",
"xin_huojun",
"chess_diaochan",
"chess_huangzhong",
@@ -1058,6 +1071,8 @@ window.noname_character_rank = {
"xiaoyuehankehan",
"zhutiexiong",
"shen_dengai",
+ "quyuan",
+ "xin_sunquan",
"libai",
"tw_gongsunfan",
"yue_caiwenji",
@@ -1131,6 +1146,10 @@ window.noname_character_rank = {
"mb_simafu",
],
b: [
+ "star_zhangzhao",
+ "dc_sp_zhurong",
+ "hansong",
+ "yue_zhugeguo",
"std_dc_yanghu",
"std_re_dengzhi",
"std_mateng",
@@ -1768,6 +1787,7 @@ window.noname_character_rank = {
],
rarity: {
legend: [
+ "ol_feiyi",
"dc_wuyi",
"sp_sunce",
"star_caoren",
@@ -1921,6 +1941,8 @@ window.noname_character_rank = {
"tw_shen_lvmeng",
"zhangjinyun",
"sunwukong",
+ "quyuan",
+ "xin_sunquan",
"libai",
"old_lingju",
"wu_zhugeliang",
@@ -1968,6 +1990,8 @@ window.noname_character_rank = {
"jsrg_yuanshao",
],
epic: [
+ "dc_sb_zhangxiu",
+ "ol_jiangwan",
"xukun",
"clan_zhongyao",
"dc_caoshuang",
@@ -2261,8 +2285,17 @@ window.noname_character_rank = {
"jsrg_zhangjiao",
"ol_sb_pangtong",
"dc_sb_zhugejin",
+ "yue_miheng",
+ "hansong",
+ "star_zhangzhao",
+ "dc_sp_zhurong",
],
rare: [
+ "dc_sb_caoang",
+ "dc_sb_guanping",
+ "yue_zhugeguo",
+ "yue_zoushi",
+ "chezhou",
"std_sunhao",
"std_chengpu",
"std_mayunlu",
@@ -2287,6 +2320,8 @@ window.noname_character_rank = {
"zhugemengxue",
"ol_sb_taishici",
"clan_wuqiao",
+ "caimao",
+ "yj_ehuan",
"xin_huojun",
"muludawang",
"mb_huban",
@@ -2780,8 +2815,10 @@ window.noname_character_rank = {
"mb_simafu",
"sb_handang",
"sb_gongsunzan",
+ "matie",
],
junk: [
+ "ol_peixiu",
"ol_sb_guanyu",
"junk_guanyu",
"sunshao",
@@ -2832,6 +2869,7 @@ window.noname_character_rank = {
"junk_xuyou",
"re_zhongyao",
"junk_zhangjiao",
+ "zhupeilan",
],
},
};
diff --git a/character/refresh/skill.js b/character/refresh/skill.js
index 7390100bc..123f9b54a 100644
--- a/character/refresh/skill.js
+++ b/character/refresh/skill.js
@@ -335,7 +335,6 @@ const skills = {
}
return bool;
},
- ai: { combo: "rejijun" },
},
//界司马朗
requji: {
@@ -1192,7 +1191,7 @@ const skills = {
//OL界火诸葛
olhuoji: {
audio: "rehuoji",
- audioname: ["ol_sp_zhugeliang"],
+ audioname: ["ol_sp_zhugeliang", "ol_pangtong"],
trigger: { player: "huogongBegin" },
forced: true,
locked: false,
@@ -1635,9 +1634,12 @@ const skills = {
return target.countCards("he") > 0 && target != player;
})
.set("ai", target => {
- var player = _status.event.player;
- if (_status.event.goon) return get.attitude(player, target) * Math.sqrt(target.countCards("he"));
- return (-get.attitude(player, target) / (target.countCards("he") + 1)) * 10;
+ var player = _status.event.player, att = get.attitude(player, target);
+ if (_status.event.goon) {
+ if (att > 0) return att * Math.sqrt(target.countCards("he"));
+ return (1 - att) / (target.countCards("he") + 1);
+ }
+ return -10 * att / (target.countCards("he") + 1);
})
.set("goon", player.countCards("hs", card => player.hasValueTarget(card)) >= 2);
"step 1";
@@ -1661,6 +1663,14 @@ const skills = {
},
subSkill: {
effect: {
+ mod: {
+ aiOrder(player, card, num) {
+ if (num <= 0 || !player.getExpansions("rekuangbi_effect").length) return;
+ let suit = get.suit(card);
+ if (player.getExpansions("rekuangbi_effect").some(i => get.suit(i) == suit)) return num + 10;
+ return num / 4;
+ }
+ },
trigger: { player: "useCard" },
charlotte: true,
forced: true,
@@ -3189,7 +3199,7 @@ const skills = {
threaten: 0.9,
effect: {
target: function (card, player, target) {
- if (player.hasSkillTag("jueqing")) return;
+ if (player.hasSkillTag("jueqing", false, target)) return;
if (target.hujia) return;
if (player._shibei_tmp) return;
if (target.hasSkill("shibei_ai")) return;
@@ -9351,7 +9361,8 @@ const skills = {
},
olpaoxiao: {
audio: "paoxiao",
- audioname: ["re_zhangfei", "guanzhang", "xiahouba", "re_guanzhang"],
+ audioname: ["re_zhangfei", "xiahouba", "re_guanzhang"],
+ audioname2: { guanzhang: "paoxiao_guanzhang" },
trigger: { player: "shaMiss" },
forced: true,
content: function () {
@@ -9368,7 +9379,8 @@ const skills = {
trigger: { source: "damageBegin1" },
forced: true,
audio: "paoxiao",
- audioname: ["re_zhangfei", "guanzhang", "xiahouba", "re_guanzhang"],
+ audioname: ["re_zhangfei", "xiahouba", "re_guanzhang"],
+ audioname2: { guanzhang: "paoxiao_guanzhang" },
filter: function (event, player) {
return event.card && event.card.name == "sha" && player.countMark("olpaoxiao2") > 0;
},
@@ -9780,6 +9792,9 @@ const skills = {
player.recover();
player.draw();
},
+ ai: {
+ combo: "rejiushi"
+ },
},
rejiushi: {
audio: 2,
@@ -11146,7 +11161,7 @@ const skills = {
let name = _status.characterlist[i];
if (name.indexOf("zuoci") != -1 || name.indexOf("key_") == 0 || name.indexOf("sp_key_") == 0 || get.is.double(name) || lib.skill.rehuashen.banned.includes(name) || player.storage.rehuashen.character.includes(name)) continue;
let skills = lib.character[name][3].filter(skill => {
- const categories = get.skillCategoriesOf(skill);
+ const categories = get.skillCategoriesOf(skill, player);
return !categories.some(type => lib.skill.rehuashen.bannedType.includes(type));
});
if (skills.length) {
@@ -11200,7 +11215,7 @@ const skills = {
node = ui.create.buttonPresets.character(item, "character", position, noclick);
const info = lib.character[item];
const skills = info[3].filter(function (skill) {
- const categories = get.skillCategoriesOf(skill);
+ const categories = get.skillCategoriesOf(skill, get.player());
return !categories.some(type => lib.skill.rehuashen.bannedType.includes(type));
});
if (skills.length) {
@@ -12238,6 +12253,7 @@ const skills = {
},
new_retuxi: {
audio: "retuxi",
+ audioname2: { gz_jun_caocao: "jianan_tuxi" },
trigger: {
player: "phaseDrawBegin2",
},
@@ -12472,9 +12488,12 @@ const skills = {
},
locked: false,
audio: "wusheng",
- audioname: ["re_guanyu", "guanzhang", "jsp_guanyu", "guansuo", "re_guanzhang", "dc_jsp_guanyu"],
+ audioname: ["re_guanyu", "jsp_guanyu", "re_guanzhang", "dc_jsp_guanyu"],
audioname2: {
dc_guansuo: "wusheng_guansuo",
+ guanzhang: "wusheng_guanzhang",
+ guansuo: "wusheng_guansuo",
+ gz_jun_liubei: "shouyue_wusheng"
},
enable: ["chooseToRespond", "chooseToUse"],
filterCard: function (card, player) {
@@ -12509,7 +12528,6 @@ const skills = {
},
},
},
- wusheng_guansuo: { audio: 2 },
new_yijue: {
audio: "yijue",
enable: "phaseUse",
@@ -12829,8 +12847,8 @@ const skills = {
ai: {
effect: {
target: (card, player, target) => {
- if (typeof card !== "object" || !get.tag(card, "damage") || target.hasSkill("gangzhi")) return;
- if (player.hasSkillTag("jueqing", null, true)) return;
+ if (typeof card !== "object" || !get.tag(card, "damage")) return;
+ if (player.hasSkillTag("jueqing", false, target)) return;
if (get.color(card) === "red") return [1, 0, 1, 0.6];
return [1, 0.6];
},
@@ -13840,7 +13858,8 @@ const skills = {
audioname2: {
re_sunyi: "reyingzi_re_sunyi",
heqi: "reyingzi_heqi",
- re_heqi: "reyingzi_heqi"
+ re_heqi: "reyingzi_heqi",
+ boss_sunce: "reyingzi_sunce"
},
trigger: { player: "phaseDrawBegin2" },
forced: true,
@@ -14568,7 +14587,7 @@ const skills = {
},
zhaxiang: {
audio: 2,
- audioname: ["ol_sb_jiangwei"],
+ audioname2: { ol_sb_jiangwei: "zhaxiang_ol_sb_jiangwei" },
trigger: { player: "loseHpEnd" },
forced: true,
content: function () {
@@ -14627,7 +14646,7 @@ const skills = {
charlotte: true,
onremove: true,
audio: "zhaxiang",
- audioname: ["ol_sb_jiangwei"],
+ audioname2: { ol_sb_jiangwei: "zhaxiang_ol_sb_jiangwei" },
trigger: { player: "useCard" },
filter: function (event, player) {
return event.card && event.card.name == "sha" && get.color(event.card) == "red";
diff --git a/character/refresh/voices.js b/character/refresh/voices.js
index 3e4fc3664..94087e4bf 100644
--- a/character/refresh/voices.js
+++ b/character/refresh/voices.js
@@ -413,7 +413,7 @@ export default {
"#liuli_re_daqiao2": "帮帮人家嘛~",
"#re_daqiao:die": "伯符,再也没人能欺负我了……",
"#rekurou1": "我这把老骨头,不算什么!",
- "#rekurou2": "为成大业,死不足惜!",
+ "#rekurou2": "为成大义,死不足惜!",
"#zhaxiang1": "铁锁连舟而行,东吴水师可破!",
"#zhaxiang2": "两军阵前,不斩降将!",
"#re_huanggai:die": "盖,有负公瑾重托……",
diff --git a/character/sb/skill.js b/character/sb/skill.js
index a163c568f..efe5d5872 100644
--- a/character/sb/skill.js
+++ b/character/sb/skill.js
@@ -379,6 +379,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "sbqiaomeng"
+ },
},
sbqiaomeng: {
audio: 2,
@@ -434,6 +437,9 @@ const skills = {
if (num > 0) player.addMark("charge", num);
}
},
+ ai: {
+ combo: "sbyicong"
+ },
},
//高顺
sbxianzhen: {
@@ -1419,33 +1425,28 @@ const skills = {
break;
}
case 4: {
- let map = {};
- game.dead.forEach(target => (map[target.playerid] = get.translation(target)));
- const {
- result: { control },
- } = await player
- .chooseControl(Object.values(map))
- .set("ai", () => {
- const getNum = target => {
- let num = 0;
- if (target.name && lib.character[target.name]) num += get.rank(target.name, true);
- if (target.name2 && lib.character[target.name2]) num += get.rank(target.name2, true);
- return num;
- };
- let controls = _status.event.controls.slice();
- controls = controls.map(name => [name, game.dead.find(target => _status.event.map[target.playerid] == name)]);
- controls.sort((a, b) => getNum(b[1]) - getNum(a[1]));
- return controls[0][0];
+ const result = await player
+ .chooseTarget(
+ "行殇:请选择一名已阵亡角色",
+ (card, player, target) => {
+ return target.isDead();
+ },
+ true,
+ "获得一名已阵亡角色的所有技能,然后失去〖行殇〗〖放逐〗〖颂威〗"
+ )
+ .set("ai", target => {
+ return ["name", "name1", "name2"].reduce((sum, name) => {
+ if (!target[name] || !lib.character[target[name]] || (name == "name1" && target.name1 == target.name)) return sum;
+ return sum + get.rank(target[name], true);
+ }, 0);
})
- .set("prompt", "获得一名已阵亡角色的所有技能")
- .set("map", map);
- if (control) {
- const target2 = game.dead.find(targetx => map[targetx.playerid] == control);
+ .set("deadTarget", true)
+ .forResult();
+ if (result.bool) {
+ const target2 = result.targets[0];
player.line(target2);
game.log(player, "选择了", target2);
- const skills = target2.getStockSkills(true, true);
- const skills2 = ["sbxingshang", "sbfangzhu", "sbsongwei"];
- player.changeSkills(skills, skills2);
+ await player.changeSkills(target2.getStockSkills(true, true), ["sbxingshang", "sbfangzhu", "sbsongwei"]);
}
}
}
@@ -1485,7 +1486,7 @@ const skills = {
case 3:
return str + "移去5个“颂”标记,令一名体力上限小于10的角色加1点体力上限并回复1点体力,然后随机恢复一个被废除的装备栏";
case 4:
- return str + "移去5个“颂”标记,获得一名已阵亡角色的所有技能,然后失去武将牌上的所有技能";
+ return str + "移去5个“颂”标记,获得一名已阵亡角色的所有技能,然后失去〖行殇〗〖放逐〗〖颂威〗";
}
},
},
@@ -1896,7 +1897,7 @@ const skills = {
player.markAuto("sbyijue_effect", [trigger.player]);
},
ai: {
- halfneg: true,
+ neg: true,
},
marktext: "绝",
intro: { content: "已放$一马" },
@@ -6284,6 +6285,7 @@ const skills = {
});
},
ai: {
+ combo: "sbjushou",
order: 8,
result: {
target: -1,
@@ -6980,6 +6982,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "sbliangzhu"
+ },
},
sbliangzhu: {
audio: 2,
@@ -7183,6 +7188,9 @@ const skills = {
player.addSkills("sbduojing");
player.storage.sbkeji = true;
},
+ ai: {
+ combo: "sbkeji"
+ },
},
sbduojing: {
audio: 2,
@@ -7257,7 +7265,10 @@ const skills = {
} else player.removeSkill("sbxiayuan_round");
},
subSkill: { round: { charlotte: true } },
- ai: { expose: 0.2 },
+ ai: {
+ combo: "sbjieyue",
+ expose: 0.2
+ },
},
sbjieyue: {
audio: 4,
@@ -7412,7 +7423,6 @@ const skills = {
ai: {
threaten: 3.5,
directHit_ai: true,
- halfneg: true,
skillTagFilter: function (player, tag, arg) {
if (arg && arg.card && arg.card.name == "sha") {
var storage = player.getStorage("sbliegong");
diff --git a/character/shenhua/skill.js b/character/shenhua/skill.js
index 322234276..ae77a3d3d 100644
--- a/character/shenhua/skill.js
+++ b/character/shenhua/skill.js
@@ -451,7 +451,7 @@ const skills = {
return target.hasUseTarget(i);
});
if (cards.length) {
- const card = cards[0];
+ let card = cards[0];
if (cards.length > 1) {
const { result } = await target.chooseButton(true, ["选择要使用的装备牌", cards]).set("ai", function (button) {
return get.order(button.link);
@@ -3449,6 +3449,7 @@ const skills = {
},
qiaobian: {
audio: 2,
+ audioname2: { gz_jun_caocao: "jianan_qiaobian" },
trigger: {
player: ["phaseJudgeBefore", "phaseDrawBefore", "phaseUseBefore", "phaseDiscardBefore"],
},
@@ -4172,15 +4173,15 @@ const skills = {
},
intro: {
content(storage, player) {
- var str = "";
- var list = Object.keys(storage.owned);
+ let str = "";
+ const list = Object.keys(storage.owned);
if (list.length) {
str += get.translation(list[0]);
- for (var i = 1; i < list.length; i++) {
+ for (let i = 1; i < list.length; i++) {
str += "、" + get.translation(list[i]);
}
}
- var skill = player.storage.huashen.current2;
+ const skill = player.storage.huashen.current2;
if (skill) {
str += "当前技能:" + get.translation(skill);
}
@@ -4191,10 +4192,10 @@ const skills = {
storage.owned = [];
},
mark(dialog, content, player) {
- var list = Object.keys(content.owned);
+ const list = Object.keys(content.owned);
if (list.length) {
- var skill = player.storage.huashen.current2;
- var character = player.storage.huashen.current;
+ const skill = player.storage.huashen.current2;
+ const character = player.storage.huashen.current;
if (skill && character) {
dialog.addSmall([[character], (item, type, position, noclick, node) => lib.skill.rehuashen.$createButton(item, type, position, noclick, node)]);
dialog.add('
【' + get.translation(lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2)) + "】
" + "
" + get.skillInfoTranslation(skill, player) + "
");
@@ -4215,11 +4216,11 @@ const skills = {
lib.skill.pingjian.initList();
}
_status.characterlist.randomSort();
- for (var i = 0; i < _status.characterlist.length; i++) {
+ for (let i = 0; i < _status.characterlist.length; i++) {
let name = _status.characterlist[i];
if (name.indexOf("zuoci") != -1 || name.indexOf("key_") == 0 || name.indexOf("sp_key_") == 0 || lib.skill.rehuashen.banned.includes(name) || player.storage.huashen.owned[name]) continue;
let skills = lib.character[name][3].filter(skill => {
- const categories = get.skillCategoriesOf(skill);
+ const categories = get.skillCategoriesOf(skill, player);
return !categories.some(type => lib.skill.rehuashen.bannedType.includes(type));
});
if (skills.length) {
@@ -4230,9 +4231,9 @@ const skills = {
}
},
addHuashens(player, num) {
- var list = [];
- for (var i = 0; i < num; i++) {
- var name = lib.skill.huashen.addHuashen(player);
+ const list = [];
+ for (let i = 0; i < num; i++) {
+ const name = lib.skill.huashen.addHuashen(player);
if (name) list.push(name);
}
if (list.length) {
@@ -4251,22 +4252,23 @@ const skills = {
if (name == "phaseBefore") return game.phaseNumber == 0;
return !get.is.empty(player.storage.huashen.owned);
},
- direct: true,
- content() {
- "step 0";
- var name = event.triggername;
+ log: false,
+ async cost(event, trigger, player) {
+ const name = event.triggername;
if (trigger.name != "phase" || (name == "phaseBefore" && game.phaseNumber == 0)) {
player.logSkill("huashen");
lib.skill.huashen.addHuashens(player, 2);
event.logged = true;
}
- var cards = [];
- var skills = [];
- for (var i in player.storage.huashen.owned) {
+ await Promise.all(event.next); // await logSkill 防止被 paused
+ // 因为化身内置了一个 chooseButtonControl 需要特殊处理一下
+ const cards = [];
+ const skills = [];
+ for (const i in player.storage.huashen.owned) {
cards.push(i);
skills.addArray(player.storage.huashen.owned[i]);
}
- var cond = event.triggername == "phaseBegin" ? "in" : "out";
+ const cond = event.triggername == "phaseBegin" ? "in" : "out";
skills.randomSort();
skills.sort(function (a, b) {
return get.skillRank(b, cond) - get.skillRank(a, cond);
@@ -4274,34 +4276,35 @@ const skills = {
if (player.isUnderControl()) {
game.swapPlayerAuto(player);
}
- var switchToAuto = function () {
+ const switchToAuto = function () {
_status.imchoosing = false;
- var skill = skills[0],
+ let skill = skills[0],
character;
- for (var i in player.storage.huashen.owned) {
+ for (const i in player.storage.huashen.owned) {
if (player.storage.huashen.owned[i].includes(skill)) {
character = i;
break;
}
}
- event._result = {
+ if (event.dialog) event.dialog.close();
+ if (event.control) event.control.close();
+ return Promise.resolve({
bool: true,
skill: skill,
character: character,
- };
- if (event.dialog) event.dialog.close();
- if (event.control) event.control.close();
+ });
};
- var chooseButton = function (player, list, forced) {
- var event = _status.event;
+ const chooseButton = function (player, list, forced) {
+ const { promise, resolve } = Promise.withResolvers();
+ const event = _status.event;
player = player || event.player;
if (!event._result) event._result = {};
- var prompt = forced ? "化身:选择获得一项技能" : get.prompt("huashen");
- var dialog = ui.create.dialog(prompt, [list, (item, type, position, noclick, node) => lib.skill.rehuashen.$createButton(item, type, position, noclick, node)]);
+ const prompt = forced ? "化身:选择获得一项技能" : get.prompt("huashen");
+ const dialog = ui.create.dialog(prompt, [list, (item, type, position, noclick, node) => lib.skill.rehuashen.$createButton(item, type, position, noclick, node)]);
event.dialog = dialog;
event.forceMine = true;
event.button = null;
- for (var i = 0; i < event.dialog.buttons.length; i++) {
+ for (let i = 0; i < event.dialog.buttons.length; i++) {
event.dialog.buttons[i].classList.add("pointerdiv");
event.dialog.buttons[i].classList.add("selectable");
}
@@ -4334,46 +4337,45 @@ const skills = {
}
event.control.replacex(["cancel2"]);
};
-
event.switchToAuto = function () {
- var cards = [];
- var skills = [];
- for (var i in player.storage.huashen.owned) {
+ const cards = [];
+ const skills = [];
+ for (const i in player.storage.huashen.owned) {
cards.push(i);
skills.addArray(player.storage.huashen.owned[i]);
}
- var cond = event.triggername == "phaseBegin" ? "in" : "out";
+ const cond = event.triggername == "phaseBegin" ? "in" : "out";
skills.randomSort();
skills.sort(function (a, b) {
return get.skillRank(b, cond) - get.skillRank(a, cond);
});
_status.imchoosing = false;
- var skill = skills[0],
+ let skill = skills[0],
character;
- for (var i in player.storage.huashen.owned) {
+ for (const i in player.storage.huashen.owned) {
if (player.storage.huashen.owned[i].includes(skill)) {
character = i;
break;
}
}
- event._result = {
+ resolve({
bool: true,
skill: skill,
character: character,
- };
+ });
if (event.dialog) event.dialog.close();
if (event.control) event.control.close();
};
- var controls = [];
+ const controls = [];
event.control = ui.create.control();
event.control.replacex = function () {
- var args = Array.from(arguments)[0];
+ const args = Array.from(arguments)[0];
if (args.includes("cancel2") && forced) {
args.remove("cancel2");
this.style.opacity = "";
}
args.push(function (link) {
- var result = event._result;
+ const result = event._result;
if (link == "cancel2") result.bool = false;
else {
if (!event.button) return;
@@ -4383,8 +4385,9 @@ const skills = {
}
event.dialog.close();
event.control.close();
- game.resume();
+ // game.resume(); // 不再 game.resume 防止 game.loop 被重复执行
_status.imchoosing = false;
+ resolve(result);
});
return this.replace.apply(this, args);
};
@@ -4393,67 +4396,77 @@ const skills = {
event.control.style.opacity = 1;
}
event.control.replacex(controls);
- game.pause();
+ game.pause(); // 暂停 game.loop 防止 game.resume2
game.countChoose();
+ return promise;
};
+ let next;
if (event.isMine()) {
- chooseButton(player, cards, event.logged);
+ next = chooseButton(player, cards, event.logged);
} else if (event.isOnline()) {
+ const { promise, resolve } = Promise.withResolvers();
event.player.send(chooseButton, event.player, cards, event.logged);
- event.player.wait();
- game.pause();
+ event.player.wait(result => !!void resolve(result)); // 不再 game.resume 防止 game.loop 被重复执行
+ game.pause(); // 暂停 game.loop 防止 game.resume2
+ next = promise;
} else {
- switchToAuto();
+ next = switchToAuto();
}
- "step 1";
- var map = event.result || result;
- if (map.bool) {
- if (!event.logged) player.logSkill("huashen");
- var skill = map.skill,
- character = map.character;
- if (character != player.storage.huashen.current) {
- const old = player.storage.huashen.current;
- player.storage.huashen.current = character;
- player.markSkill("huashen");
- game.broadcastAll(
- function (player, character, old) {
- player.tempname.remove(old);
- player.tempname.add(character);
- player.sex = lib.character[character][0];
- //player.group=lib.character[character][1];
- //player.node.name.dataset.nature=get.groupnature(player.group);
- var mark = player.marks.huashen;
- if (mark) {
- mark.style.transition = "all 0.3s";
- setTimeout(function () {
- mark.style.transition = "all 0s";
- ui.refresh(mark);
- mark.setBackground(character, "character");
- if (mark.firstChild) {
- mark.firstChild.remove();
- }
- setTimeout(function () {
- mark.style.transition = "";
- mark.show();
- }, 50);
- }, 200);
+ const result = await next;
+ _status.paused = false; // 恢复 game.loop 但不立刻执行
+ result.logged = event.logged;
+ event.result = {
+ bool: result.bool,
+ cost_data: result,
+ };
+ },
+ async content(event, trigger, player) {
+ const map = event.cost_data;
+ if (!map.logged) player.logSkill("huashen");
+ const skill = map.skill,
+ character = map.character;
+ if (character != player.storage.huashen.current) {
+ const old = player.storage.huashen.current;
+ player.storage.huashen.current = character;
+ player.markSkill("huashen");
+ game.broadcastAll(
+ function (player, character, old) {
+ player.tempname.remove(old);
+ player.tempname.add(character);
+ player.sex = lib.character[character].sex;
+ //player.group=lib.character[character][1];
+ //player.node.name.dataset.nature=get.groupnature(player.group);
+ const mark = player.marks.huashen;
+ if (!mark) return;
+ mark.style.transition = "all 0.3s";
+ setTimeout(function () {
+ mark.style.transition = "all 0s";
+ ui.refresh(mark);
+ mark.setBackground(character, "character");
+ if (mark.firstChild) {
+ mark.firstChild.remove();
}
- },
- player,
- character,
- old
- );
- game.log(player, "将性别变为了", "#y" + get.translation(lib.character[character][0]) + "性");
- player.changeGroup(lib.character[character][1]);
- }
- player.storage.huashen.current2 = skill;
- if (!player.additionalSkills.huashen || !player.additionalSkills.huashen.includes(skill)) {
- player.addAdditionalSkills("huashen", skill);
- player.flashAvatar("huashen", character);
- player.syncStorage("huashen");
- player.updateMarks("huashen");
- // lib.skill.rehuashen.createAudio(character,skill,'zuoci');
- }
+ setTimeout(function () {
+ mark.style.transition = "";
+ mark.show();
+ }, 50);
+ }, 200);
+ },
+ player,
+ character,
+ old
+ );
+ get.character().group;
+ game.log(player, "将性别变为了", "#y" + get.translation(lib.character[character].sex) + "性");
+ await player.changeGroup(lib.character[character].group);
+ }
+ player.storage.huashen.current2 = skill;
+ if (!player.additionalSkills.huashen || !player.additionalSkills.huashen.includes(skill)) {
+ player.flashAvatar("huashen", character);
+ player.syncStorage("huashen");
+ player.updateMarks("huashen");
+ await player.addAdditionalSkills("huashen", skill);
+ // lib.skill.rehuashen.createAudio(character,skill,'zuoci');
}
},
},
@@ -4463,20 +4476,11 @@ const skills = {
unique: true,
trigger: { player: "damageEnd" },
frequent: true,
- content() {
- "step 0";
- event.num = trigger.num;
- "step 1";
+ getIndex(event, player) {
+ return event.num;
+ },
+ async content(event, trigger, player) {
lib.skill.huashen.addHuashens(player, 1);
- "step 2";
- if (--event.num > 0 && player.hasSkill(event.name) && !get.is.blocked(event.name, player)) {
- player.chooseBool(get.prompt2("xinsheng")).set("frequentSkill", event.name);
- } else event.finish();
- "step 3";
- if (result.bool && player.hasSkill("xinsheng")) {
- player.logSkill("xinsheng");
- event.goto(1);
- }
},
ai: {
combo: "huashen",
@@ -4505,7 +4509,7 @@ const skills = {
filter(event, player) {
return event.card.name == "nanman";
},
- content() {
+ async content(event, trigger, player) {
trigger.cancel();
},
},
@@ -4517,7 +4521,7 @@ const skills = {
filter(event, player) {
return event.card && event.card.name == "nanman" && event.player != player;
},
- content() {
+ async content(event, trigger, player) {
trigger.customArgs.default.customSource = player;
},
},
@@ -4539,26 +4543,21 @@ const skills = {
}
return true;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
trigger.changeToZero();
event.cards = get.cards(player.getDamagedHp() + (event.name == "zaiqi" ? 0 : 1));
- game.cardsGotoOrdering(event.cards);
- player.showCards(event.cards);
- "step 1";
- var num = 0;
- for (var i = 0; i < event.cards.length; i++) {
+ await game.cardsGotoOrdering(event.cards);
+ await player.showCards(event.cards);
+ let num = 0;
+ for (let i = 0; i < event.cards.length; i++) {
if (get.suit(event.cards[i]) == "heart") {
num++;
event.cards.splice(i--, 1);
}
}
- if (num) {
- player.recover(num);
- }
- "step 2";
+ if (num) await player.recover(num);
if (event.cards.length) {
- player.gain(event.cards, "gain2");
+ await player.gain(event.cards, "gain2");
}
},
ai: {
@@ -4593,7 +4592,7 @@ const skills = {
filter(event, player) {
return event.card.name == "nanman";
},
- content() {
+ async content(event, trigger, player) {
trigger.cancel();
},
},
@@ -4605,8 +4604,8 @@ const skills = {
filter(event, player) {
return event.card.name == "nanman" && event.player != player && event.cards.someInD();
},
- content() {
- player.gain(trigger.cards.filterInD(), "gain2");
+ async content(event, trigger, player) {
+ await player.gain(trigger.cards.filterInD(), "gain2");
},
},
lieren: {
@@ -4622,12 +4621,10 @@ const skills = {
return get.attitude(player, event.player) < 0 && player.countCards("h") > 1;
},
//priority:5,
- content() {
- "step 0";
- player.chooseToCompare(trigger.player);
- "step 1";
+ async content(event, trigger, player) {
+ const { result } = await player.chooseToCompare(trigger.player);
if (result.bool && trigger.player.countGainableCards(player, "he")) {
- player.gainPlayerCard(trigger.player, true, "he");
+ await player.gainPlayerCard(trigger.player, true, "he");
}
},
},
@@ -4638,32 +4635,29 @@ const skills = {
filter(event) {
return event.player.countCards("he") > 0;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
event.togain = trigger.player.getCards("he");
- player.gain(event.togain, trigger.player, "giveAuto", "bySelf");
+ await player.gain(event.togain, trigger.player, "giveAuto", "bySelf");
},
},
fangzhu: {
audio: 2,
trigger: { player: "damageEnd" },
- direct: true,
preHidden: true,
- content() {
- "step 0";
- var draw = player.getDamagedHp();
- player
+ async cost(event, trigger, player) {
+ const draw = player.getDamagedHp();
+ event.result = await player
.chooseTarget(get.prompt("fangzhu"), "令一名其他角色翻面" + (draw > 0 ? "并摸" + get.cnNumber(draw) + "张牌" : ""), function (card, player, target) {
return player != target;
})
.setHiddenSkill("fangzhu")
.set("ai", target => {
if (target.hasSkillTag("noturn")) return 0;
- var player = _status.event.player;
- var current = _status.currentPhase;
- var dis = current ? get.distance(current, target, "absolute") : 1;
- var draw = player.getDamagedHp();
- var att = get.attitude(player, target);
+ const player = _status.event.player;
+ const current = _status.currentPhase;
+ const dis = current ? get.distance(current, target, "absolute") : 1;
+ const draw = player.getDamagedHp();
+ const att = get.attitude(player, target);
if (att == 0) return target.hasJudge("lebu") ? Math.random() / 3 : Math.sqrt(get.threaten(target)) / 5 + Math.random() / 2;
if (att > 0) {
if (target.isTurnedOver()) return att + draw;
@@ -4676,14 +4670,13 @@ const skills = {
if (current && target.getSeatNum() <= current.getSeatNum()) return -att + draw / 3;
return (4.25 - draw) * 10 * Math.sqrt(Math.max(0.01, get.threaten(target))) + (2 * game.countPlayer()) / dis;
}
- });
- "step 1";
- if (result.bool) {
- player.logSkill("fangzhu", result.targets);
- var draw = player.getDamagedHp();
- if (draw > 0) result.targets[0].draw(draw);
- result.targets[0].turnOver();
- }
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const draw = player.getDamagedHp();
+ if (draw > 0) await event.targets[0].draw(draw);
+ await event.targets[0].turnOver();
},
ai: {
maixie: true,
@@ -4694,10 +4687,10 @@ const skills = {
if (player.hasSkillTag("jueqing", false, target)) return [1, -2];
if (target.hp <= 1) return;
if (!target.hasFriend()) return;
- var hastarget = false;
- var turnfriend = false;
- var players = game.filterPlayer();
- for (var i = 0; i < players.length; i++) {
+ let hastarget = false;
+ let turnfriend = false;
+ const players = game.filterPlayer();
+ for (let i = 0; i < players.length; i++) {
if (get.attitude(target, players[i]) < 0 && !players[i].isTurnedOver()) {
hastarget = true;
}
@@ -4731,16 +4724,15 @@ const skills = {
if (event.result.color != "black") return false;
return player.hasZhuSkill("songwei", event.player);
},
- direct: true,
- content() {
- "step 0";
- trigger.player.chooseBool("是否发动【颂威】,令" + get.translation(player) + "摸一张牌?").set("choice", get.attitude(trigger.player, player) > 0);
- "step 1";
- if (result.bool) {
- player.logSkill("songwei2");
- trigger.player.line(player, "green");
- player.draw();
- }
+ async cost(event, trigger, player) {
+ event.result = await trigger.player
+ .chooseBool("是否发动【颂威】,令" + get.translation(player) + "摸一张牌?")
+ .set("choice", get.attitude(trigger.player, player) > 0)
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.player.line(player, "green");
+ player.draw();
},
},
jiezi: {
@@ -4750,8 +4742,8 @@ const skills = {
filter(event, player) {
return event.player != player;
},
- content() {
- player.draw();
+ async content(event, trigger, player) {
+ await player.draw();
},
},
gzduanliang: {
@@ -4830,7 +4822,7 @@ const skills = {
})
);
},
- content() {
+ async content(event, trigger, player) {
trigger.num += 2;
player.addSkill("haoshi2");
},
@@ -4849,14 +4841,10 @@ const skills = {
forced: true,
popup: false,
audio: false,
- content() {
- "step 0";
+ async content(event, trigger, player) {
player.removeSkill("haoshi2");
- if (player.countCards("h") <= 5) {
- event.finish();
- return;
- }
- player.chooseCardTarget({
+ if (player.countCards("h") <= 5) return;
+ const { result } = await player.chooseCardTarget({
selectCard: Math.floor(player.countCards("h") / 2),
filterTarget(card, player, target) {
return target.isMinHandcard();
@@ -4867,9 +4855,8 @@ const skills = {
return get.attitude(_status.event.player, target);
},
});
- "step 1";
if (result.targets && result.targets[0]) {
- player.give(result.cards, result.targets[0]);
+ await player.give(result.cards, result.targets[0]);
}
},
},
@@ -4879,7 +4866,7 @@ const skills = {
usable: 1,
position: "he",
filterCard() {
- var targets = ui.selected.targets;
+ const targets = ui.selected.targets;
if (targets.length == 2) {
if (Math.abs(targets[0].countCards("h") - targets[1].countCards("h")) <= ui.selected.cards.length) return false;
}
@@ -4893,32 +4880,31 @@ const skills = {
return true;
},
filterOk() {
- var targets = ui.selected.targets;
+ const targets = ui.selected.targets;
if (targets.length != 2) return false;
return Math.abs(targets[0].countCards("h") - targets[1].countCards("h")) == ui.selected.cards.length;
},
multitarget: true,
multiline: true,
- content() {
- targets[0].swapHandcards(targets[1]);
+ async content(event, trigger, player) {
+ event.targets[0].swapHandcards(event.targets[1]);
},
check(card) {
- var list = [],
+ const list = [],
player = _status.event.player;
- var num = player.countCards("he");
- var count;
- var players = game.filterPlayer();
- for (var i = 0; i < players.length; i++) {
+ const num = player.countCards("he");
+ const players = game.filterPlayer();
+ let count;
+ for (let i = 0; i < players.length; i++) {
if (players[i] != player && get.attitude(player, players[i]) > 3) list.push(players[i]);
}
list.sort(function (a, b) {
return a.countCards("h") - b.countCards("h");
});
if (list.length == 0) return -1;
- var from = list[0];
+ const from = list[0];
list.length = 0;
-
- for (var i = 0; i < players.length; i++) {
+ for (let i = 0; i < players.length; i++) {
if (players[i] != player && get.attitude(player, players[i]) < 1) list.push(players[i]);
}
if (list.length == 0) return -1;
@@ -4926,7 +4912,7 @@ const skills = {
return b.countCards("h") - a.countCards("h");
});
if (from.countCards("h") >= list[0].countCards("h")) return -1;
- for (var i = 0; i < list.length && from.countCards("h") < list[i].countCards("h"); i++) {
+ for (let i = 0; i < list.length && from.countCards("h") < list[i].countCards("h"); i++) {
if (list[i].countCards("h") - from.countCards("h") <= num) {
count = list[i].countCards("h") - from.countCards("h");
break;
@@ -4942,11 +4928,11 @@ const skills = {
expose: 0.9,
result: {
target(player, target) {
- var list = [];
- var num = player.countCards("he");
- var players = game.filterPlayer();
+ const list = [];
+ const num = player.countCards("he");
+ const players = game.filterPlayer();
if (ui.selected.targets.length == 0) {
- for (var i = 0; i < players.length; i++) {
+ for (let i = 0; i < players.length; i++) {
if (players[i] != player && get.attitude(player, players[i]) > 3) list.push(players[i]);
}
list.sort(function (a, b) {
@@ -4955,17 +4941,17 @@ const skills = {
if (target == list[0]) return get.attitude(player, target);
return -get.attitude(player, target);
} else {
- var from = ui.selected.targets[0];
- for (var i = 0; i < players.length; i++) {
+ const from = ui.selected.targets[0];
+ for (let i = 0; i < players.length; i++) {
if (players[i] != player && get.attitude(player, players[i]) < 1) list.push(players[i]);
}
list.sort(function (a, b) {
return b.countCards("h") - a.countCards("h");
});
if (from.countCards("h") >= list[0].countCards("h")) return -get.attitude(player, target);
- for (var i = 0; i < list.length && from.countCards("h") < list[i].countCards("h"); i++) {
+ for (let i = 0; i < list.length && from.countCards("h") < list[i].countCards("h"); i++) {
if (list[i].countCards("h") - from.countCards("h") <= num) {
- var count = list[i].countCards("h") - from.countCards("h");
+ const count = list[i].countCards("h") - from.countCards("h");
if (count < 2 && from.countCards("h") >= 2) return -get.attitude(player, target);
if (target == list[i]) return get.attitude(player, target);
return -get.attitude(player, target);
@@ -4982,6 +4968,7 @@ const skills = {
audioname2: {
re_sunyi: "gzyinghun_re_sunyi",
tw_ol_sunjian: "yinghun_ol_sunjian",
+ boss_sunce: "yinghun_sunce"
},
mod: {
aiOrder(player, card, num) {
@@ -4993,16 +4980,14 @@ const skills = {
},
locked: false,
trigger: { player: "phaseZhunbeiBegin" },
- direct: true,
preHidden: true,
- content() {
- "step 0";
- player
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseTarget(get.prompt2("yinghun"), function (card, player, target) {
return player != target;
})
.set("ai", function (target) {
- var player = _status.event.player;
+ const player = _status.event.player;
if (player.getDamagedHp() == 1 && target.countCards("he") == 0) {
return 0;
}
@@ -5014,35 +4999,32 @@ const skills = {
}
return 1;
})
- .setHiddenSkill(event.name);
- "step 1";
- if (result.bool) {
- event.num = player.getDamagedHp();
- player.logSkill(event.name, result.targets);
- event.target = result.targets[0];
- if (event.num == 1) {
- event.directcontrol = true;
- } else {
- var str1 = "摸" + get.cnNumber(event.num, true) + "弃一";
- var str2 = "摸一弃" + get.cnNumber(event.num, true);
- player
+ .setHiddenSkill(event.name)
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const num = player.getDamagedHp();
+ const [target] = event.targets;
+ let directcontrol = num == 1;
+ if (!directcontrol) {
+ const str1 = "摸" + get.cnNumber(num, true) + "弃一";
+ const str2 = "摸一弃" + get.cnNumber(num, true);
+ directcontrol =
+ str ==
+ (await player
.chooseControl(str1, str2, function (event, player) {
if (player.isHealthy()) return 1 - _status.event.choice;
return _status.event.choice;
})
- .set("choice", get.attitude(player, event.target) > 0 ? 0 : 1);
- event.str = str1;
- }
- } else {
- event.finish();
+ .set("choice", get.attitude(player, target) > 0 ? 0 : 1)
+ .forResultControl());
}
- "step 2";
- if (event.directcontrol || result.control == event.str) {
- if (event.num > 0) event.target.draw(event.num);
- event.target.chooseToDiscard(true, "he");
+ if (directcontrol) {
+ if (num > 0) await target.draw(num);
+ await target.chooseToDiscard(true, "he");
} else {
- event.target.draw();
- if (event.num > 0) event.target.chooseToDiscard(event.num, true, "he");
+ await target.draw();
+ if (num > 0) await target.chooseToDiscard(num, true, "he");
}
},
ai: {
@@ -5088,16 +5070,14 @@ const skills = {
filter(event, player) {
return player.getDamagedHp() > 0;
},
- direct: true,
preHidden: true,
- content() {
- "step 0";
- player
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseTarget(get.prompt2("gzyinghun"), function (card, player, target) {
return player != target;
})
.set("ai", function (target) {
- var player = _status.event.player;
+ const player = _status.event.player;
if (player.getDamagedHp() == 1 && target.countCards("he") == 0) {
return 0;
}
@@ -5109,34 +5089,31 @@ const skills = {
}
return 1;
})
- .setHiddenSkill(event.name);
- "step 1";
- if (result.bool) {
- event.num = player.getDamagedHp();
- player.logSkill(event.name, result.targets);
- event.target = result.targets[0];
- if (event.num == 1) {
- event.directcontrol = true;
- } else {
- var str1 = "摸" + get.cnNumber(event.num, true) + "弃一";
- var str2 = "摸一弃" + get.cnNumber(event.num, true);
- player
+ .setHiddenSkill(event.name)
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const num = player.getDamagedHp();
+ const [target] = event.targets;
+ let directcontrol = num == 1;
+ if (!directcontrol) {
+ const str1 = "摸" + get.cnNumber(num, true) + "弃一";
+ const str2 = "摸一弃" + get.cnNumber(num, true);
+ directcontrol =
+ str1 ==
+ (await player
.chooseControl(str1, str2, function (event, player) {
return _status.event.choice;
})
- .set("choice", get.attitude(player, event.target) > 0 ? str1 : str2);
- event.str = str1;
- }
- } else {
- event.finish();
+ .set("choice", get.attitude(player, target) > 0 ? str1 : str2)
+ .forResultControl());
}
- "step 2";
- if (event.directcontrol || result.control == event.str) {
- event.target.draw(event.num);
- event.target.chooseToDiscard(true, "he");
+ if (directcontrol) {
+ await target.draw(num);
+ await target.chooseToDiscard(true, "he");
} else {
- event.target.draw();
- event.target.chooseToDiscard(event.num, true, "he");
+ await target.draw();
+ await target.chooseToDiscard(num, true, "he");
}
},
ai: {
@@ -5199,9 +5176,9 @@ const skills = {
check(event, player) {
return player == event.player;
},
- content() {
- var id = (player == trigger.player ? trigger.target : player).playerid;
- var map = trigger.getParent().customArgs;
+ async content(event, trigger, player) {
+ const id = (player == trigger.player ? trigger.target : player).playerid;
+ const map = trigger.getParent().customArgs;
if (!map[id]) map[id] = {};
if (typeof map[id].shanRequired == "number") {
map[id].shanRequired++;
@@ -5220,7 +5197,8 @@ const skills = {
},
benghuai: {
audio: 2,
- audioname: ["zhugedan", "re_dongzhuo", "ol_dongzhuo", "re_zhugedan"],
+ audioname: ["re_dongzhuo", "ol_dongzhuo", "re_zhugedan"],
+ audioname2: { zhugedan: "benghuai_zhugedan" },
trigger: { player: "phaseJieshuBegin" },
forced: true,
check() {
@@ -5229,21 +5207,17 @@ const skills = {
filter(event, player) {
return !player.isMinHp() && !player.hasSkill("rejiuchi_air") && !player.hasSkill("oljiuchi_air");
},
- content() {
- "step 0";
- player
+ async content(event, trigger, player) {
+ const control = await player
.chooseControl("baonue_hp", "baonue_maxHp", function (event, player) {
if (player.hp == player.maxHp) return "baonue_hp";
if (player.hp < player.maxHp - 1 || player.hp <= 2) return "baonue_maxHp";
return "baonue_hp";
})
- .set("prompt", "崩坏:失去1点体力或减1点体力上限");
- "step 1";
- if (result.control == "baonue_hp") {
- player.loseHp();
- } else {
- player.loseMaxHp(true);
- }
+ .set("prompt", "崩坏:失去1点体力或减1点体力上限")
+ .forResultControl();
+ if (control == "baonue_hp") await player.loseHp();
+ else await player.loseMaxHp(true);
},
ai: {
threaten: 0.5,
@@ -5266,26 +5240,24 @@ const skills = {
if (player == event.source || !event.source || event.source.group != "qun") return false;
return player.hasZhuSkill("baonue", event.source);
},
- direct: true,
- content() {
- "step 0";
- trigger.source.chooseBool("是否对" + get.translation(player) + "发动【暴虐】?").set("choice", get.attitude(trigger.source, player) > 0);
- "step 1";
- if (result.bool) {
- player.logSkill("baonue");
- trigger.source.line(player, "green");
- trigger.source.judge(function (card) {
- if (get.suit(card) == "spade") return 4;
- return 0;
- }).judge2 = function (result) {
- return result.bool ? true : false;
- };
- } else {
- event.finish();
- }
- "step 2";
+ async cost(event, trigger, player) {
+ event.result = await trigger.source
+ .chooseBool("是否对" + get.translation(player) + "发动【暴虐】?")
+ .set("choice", get.attitude(trigger.source, player) > 0)
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.source.line(player, "green");
+ const next = trigger.source.judge(function (card) {
+ if (get.suit(card) == "spade") return 4;
+ return 0;
+ });
+ next.judge2 = function (result) {
+ return result.bool ? true : false;
+ };
+ const { result } = await next;
if (result.suit == "spade") {
- player.recover();
+ await player.recover();
}
},
},
@@ -5303,47 +5275,43 @@ const skills = {
selectTarget: -1,
multitarget: true,
multiline: true,
- content() {
- "step 0";
+ async content(event, trigger, player) {
player.awakenSkill("luanwu");
- event.current = player.next;
- event.currented = [];
- "step 1";
- event.currented.push(event.current);
- event.current.addTempClass("target");
- event.current
- .chooseToUse(
- "乱武:使用一张杀或失去1点体力",
- function (card) {
- if (get.name(card) != "sha") return false;
- return lib.filter.cardEnabled.apply(this, arguments);
- },
- function (card, player, target) {
- if (player == target) return false;
- var dist = get.distance(player, target);
- if (dist > 1) {
- if (
- game.hasPlayer(function (current) {
- return current != player && get.distance(player, current) < dist;
- })
- ) {
- return false;
+ const currented = [player];
+ let current = player.next;
+ do {
+ currented.push(current);
+ current.addTempClass("target");
+ const bool = await current
+ .chooseToUse(
+ "乱武:使用一张杀或失去1点体力",
+ function (card) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.cardEnabled.apply(this, arguments);
+ },
+ function (card, player, target) {
+ if (player == target) return false;
+ const dist = get.distance(player, target);
+ if (dist > 1) {
+ if (
+ game.hasPlayer(function (current) {
+ return current != player && get.distance(player, current) < dist;
+ })
+ ) {
+ return false;
+ }
}
+ return lib.filter.filterTarget.apply(this, arguments);
}
- return lib.filter.filterTarget.apply(this, arguments);
- }
- )
- .set("ai2", function () {
- return get.effect_use.apply(this, arguments) + 0.01;
- })
- .set("addCount", false);
- "step 2";
- if (result.bool == false) event.current.loseHp();
- event.current = event.current.next;
- if (event.current != player && !event.currented.includes(event.current)) {
- game.delay(0.5);
- event.goto(1);
- }
+ )
+ .set("ai2", function () {
+ return get.effect_use.apply(this, arguments) + 0.01;
+ })
+ .set("addCount", false)
+ .forResultBool();
+ if (!bool) await current.loseHp();
+ current = current.next;
+ } while (!currented.includes(current) && !void (await game.asyncDelay(0.5)));
},
ai: {
order: 1,
@@ -5352,10 +5320,10 @@ const skills = {
if (lib.config.mode == "identity" && game.zhu.isZhu && player.identity == "fan") {
if (game.zhu.hp == 1 && game.zhu.countCards("h") <= 2) return 1;
}
- var num = 0;
- var players = game.filterPlayer();
- for (var i = 0; i < players.length; i++) {
- var att = get.attitude(player, players[i]);
+ const players = game.filterPlayer();
+ let num = 0;
+ for (let i = 0; i < players.length; i++) {
+ let att = get.attitude(player, players[i]);
if (att > 0) att = 1;
if (att < 0) att = -1;
if (players[i] != player && players[i].hp <= 3) {
@@ -5389,7 +5357,7 @@ const skills = {
filter(event, player, name) {
return _status.currentPhase == player && event.player != player;
},
- content() {},
+ async content() {},
},
wansha2: {
mod: {
@@ -5414,7 +5382,7 @@ const skills = {
if (get.color(event.card) != "black") return false;
return (event.card.name == "nanman" && player != event.player) || (event.card.name == "wanjian" && player != event.player) || (event.card.name == "taoyuan" && player.hp < player.maxHp) || event.card.name == "wugu";
},
- content() {},
+ async content() {},
mod: {
targetEnabled(card) {
if ((get.type(card) == "trick" || get.type(card) == "delay") && get.color(card) == "black") return false;
@@ -5434,7 +5402,7 @@ const skills = {
position: "hs",
prompt: "将一张红色牌当火攻使用",
check(card) {
- var player = get.player();
+ const player = get.player();
if (player.countCards("h") > player.hp) {
return 6 - get.value(card);
}
@@ -5491,13 +5459,13 @@ const skills = {
mod: {
aiValue(player, card, num) {
if (get.name(card) != "wuxie" && get.color(card) != "black") return;
- var cards = player.getCards("hs", function (card) {
+ const cards = player.getCards("hs", function (card) {
return get.name(card) == "wuxie" || get.color(card) == "black";
});
cards.sort(function (a, b) {
return (get.name(b) == "wuxie" ? 1 : 2) - (get.name(a) == "wuxie" ? 1 : 2);
});
- var geti = function () {
+ const geti = function () {
if (cards.includes(card)) {
return cards.indexOf(card);
}
@@ -5523,7 +5491,7 @@ const skills = {
position: "hs",
prompt: "将一张黑色手牌当无懈可击使用",
check(card) {
- var tri = _status.event.getTrigger();
+ const tri = _status.event.getTrigger();
if (tri && tri.card && tri.card.name == "chiling") return -1;
return 8 - get.value(card);
},
@@ -5551,20 +5519,15 @@ const skills = {
}
return false;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
player.awakenSkill("niepan");
player.storage.niepan = true;
- player.discard(player.getCards("hej"));
- "step 1";
- player.link(false);
- "step 2";
- player.turnOver(false);
- "step 3";
- player.draw(3);
- "step 4";
+ await player.discard(player.getCards("hej"));
+ await player.link(false);
+ await player.turnOver(false);
+ await player.draw(3);
if (player.hp < 3) {
- player.recover(3 - player.hp);
+ await player.recover(3 - player.hp);
}
},
ai: {
@@ -5607,20 +5570,15 @@ const skills = {
}
return false;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
player.awakenSkill("oldniepan");
player.storage.oldniepan = true;
- player.discard(player.getCards("hej"));
- "step 1";
- player.link(false);
- "step 2";
- player.turnOver(false);
- "step 3";
- player.draw(3);
- "step 4";
+ await player.discard(player.getCards("hej"));
+ await player.link(false);
+ await player.turnOver(false);
+ await player.draw(3);
if (player.hp < 3) {
- player.recover(3 - player.hp);
+ await player.recover(3 - player.hp);
}
},
ai: {
@@ -5658,47 +5616,38 @@ const skills = {
filterTarget(card, player, target) {
return target.hp > player.hp && player.canCompare(target);
},
- content() {
- "step 0";
- player.chooseToCompare(target);
- "step 1";
- if (result.bool) {
- if (
- game.hasPlayer(function (player) {
- return player != target && target.inRange(player);
- })
- ) {
- player
- .chooseTarget(function (card, player, target) {
- var source = _status.event.source;
- return target != source && source.inRange(target);
- }, true)
- .set("ai", function (target) {
- return get.damageEffect(target, _status.event.source, player);
- })
- .set("source", target);
- } else {
- event.finish();
- }
- } else {
- player.damage(target);
- event.finish();
- }
- "step 2";
- if (result.bool && result.targets && result.targets.length) {
- target.line(result.targets[0], "green");
- result.targets[0].damage(target);
- }
+ async content(event, trigger, player) {
+ const target = event.target;
+ const bool = await player.chooseToCompare(target).forResultBool();
+ if (!bool) return void (await player.damage(target));
+ if (
+ !game.hasPlayer(function (player) {
+ return player != target && target.inRange(player);
+ })
+ )
+ return;
+ const { result } = await player
+ .chooseTarget(function (card, player, target) {
+ const source = _status.event.source;
+ return target != source && source.inRange(target);
+ }, true)
+ .set("ai", function (target) {
+ return get.damageEffect(target, _status.event.source, player);
+ })
+ .set("source", target);
+ if (!result.bool || !result.targets || !result.targets.length) return;
+ target.line(result.targets[0], "green");
+ await result.targets[0].damage(target);
},
ai: {
order: 0.5,
result: {
target(player, target) {
- var att = get.attitude(player, target);
- var oc = target.countCards("h") == 1;
+ const att = get.attitude(player, target);
+ const oc = target.countCards("h") == 1;
if (att > 0 && oc) return 0;
- var players = game.filterPlayer();
- for (var i = 0; i < players.length; i++) {
+ const players = game.filterPlayer();
+ for (let i = 0; i < players.length; i++) {
if (players[i] != target && players[i] != player && target.inRange(players[i])) {
if (get.damageEffect(players[i], target, player) > 0) {
return att > 0 ? att / 2 : att - (oc ? 5 : 0);
@@ -5709,15 +5658,15 @@ const skills = {
},
player(player, target) {
if (target.hasSkillTag("jueqing", false, target)) return -10;
- var mn = 1;
- var hs = player.getCards("h");
- for (var i = 0; i < hs.length; i++) {
+ const hs = player.getCards("h");
+ let mn = 1;
+ for (let i = 0; i < hs.length; i++) {
mn = Math.max(mn, get.number(hs[i]));
}
if (mn <= 11 && player.hp < 2) return -20;
- var max = player.maxHp - hs.length;
- var players = game.filterPlayer();
- for (var i = 0; i < players.length; i++) {
+ let max = player.maxHp - hs.length;
+ const players = game.filterPlayer();
+ for (let i = 0; i < players.length; i++) {
if (get.attitude(player, players[i]) > 2) {
max = Math.max(Math.min(5, players[i].hp) - players[i].countCards("h"), max);
}
@@ -5742,31 +5691,27 @@ const skills = {
jieming: {
audio: 2,
trigger: { player: "damageEnd" },
- direct: true,
- content() {
- "step 0";
- event.count = trigger.num;
- "step 1";
- event.count--;
- player
+ getIndex(event) {
+ return event.num;
+ },
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseTarget(get.prompt2("jieming"), function (card, player, target) {
- return true; //target.countCards('h') 2) {
return Math.max(0, Math.min(5, target.maxHp) - target.countCards("h"));
}
return att / 3;
- });
- "step 2";
- if (result.bool) {
- player.logSkill("jieming", result.targets);
- for (var i = 0; i < result.targets.length; i++) {
- result.targets[i].drawTo(Math.min(5, result.targets[i].maxHp));
- }
- if (event.count && player.hasSkill("jieming")) event.goto(1);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ for (const target of event.targets) {
+ await target.drawTo(Math.min(5, target.maxHp));
}
},
ai: {
@@ -5776,9 +5721,9 @@ const skills = {
target(card, player, target, current) {
if (get.tag(card, "damage") && target.hp > 1) {
if (player.hasSkillTag("jueqing", false, target)) return [1, -2];
- var max = 0;
- var players = game.filterPlayer();
- for (var i = 0; i < players.length; i++) {
+ const players = game.filterPlayer();
+ let max = 0;
+ for (let i = 0; i < players.length; i++) {
if (get.attitude(target, players[i]) > 0) {
max = Math.max(Math.min(5, players[i].hp) - players[i].countCards("h"), max);
}
@@ -5823,13 +5768,11 @@ const skills = {
if (player == target) return false;
return player.inRange(target);
},
- content() {
- "step 0";
- if (cards.length == 0) {
- player.loseHp();
+ async content(event, trigger, player) {
+ if (event.cards.length == 0) {
+ await player.loseHp();
}
- "step 1";
- target.damage("nocard");
+ await event.target.damage("nocard");
},
check(card) {
return 10 - get.value(card);
@@ -5870,12 +5813,12 @@ const skills = {
}
},
filterCard(card) {
- var player = _status.event.player;
+ const player = _status.event.player;
if (player.hasSkill("xinqiangxi2")) return false;
return get.type(card) == "equip";
},
selectCard() {
- var player = _status.event.player;
+ const player = _status.event.player;
if (player.hasSkill("xinqiangxi2")) return -1;
if (player.hasSkill("xinqiangxi3")) return [1, 1];
return [0, 1];
@@ -5884,16 +5827,14 @@ const skills = {
if (player == target) return false;
return player.inRange(target);
},
- content() {
- "step 0";
- if (cards.length == 0) {
- player.loseHp();
+ async content(event, trigger, player) {
+ if (event.cards.length == 0) {
player.addTempSkill("xinqiangxi3");
+ await player.loseHp();
} else {
player.addTempSkill("xinqiangxi2");
}
- "step 1";
- target.damage("nocard");
+ await event.target.damage("nocard");
},
check(card) {
return 10 - get.value(card);
@@ -5926,11 +5867,9 @@ const skills = {
filter(event, player) {
return player.countCards("h") > 0;
},
- content() {
- "step 0";
- player.chooseToCompare(target);
- "step 1";
- if (result.bool) {
+ async content(event, trigger, player) {
+ const bool = await player.chooseToCompare(event.target).forResultBool();
+ if (bool) {
player.addTempSkill("tianyi2");
} else {
player.addTempSkill("tianyi3");
@@ -5938,11 +5877,11 @@ const skills = {
},
ai: {
order(name, player) {
- var cards = player.getCards("h");
+ const cards = player.getCards("h");
if (player.countCards("h", "sha") == 0) {
return 1;
}
- for (var i = 0; i < cards.length; i++) {
+ for (let i = 0; i < cards.length; i++) {
if (cards[i].name != "sha" && get.number(cards[i]) > 11 && get.value(cards[i]) < 7) {
return 9;
}
@@ -5952,14 +5891,14 @@ const skills = {
result: {
player(player) {
if (player.countCards("h", "sha") > 0) return 0.6;
- var num = player.countCards("h");
+ const num = player.countCards("h");
if (num > player.hp) return 0;
if (num == 1) return -2;
if (num == 2) return -1;
return -0.7;
},
target(player, target) {
- var num = target.countCards("h");
+ const num = target.countCards("h");
if (num == 1) return -1;
if (num == 2) return -0.7;
return -0.5;
@@ -6012,12 +5951,12 @@ const skills = {
},
preHidden: true,
prompt2: () => "进行一次判定,本回合可以将一张与此牌颜色不同的手牌当作【决斗】使用",
- content() {
- player.judge().set("callback", lib.skill.shuangxiong1.callback);
+ async content(event, trigger, player) {
trigger.changeToZero();
+ await player.judge().set("callback", lib.skill.shuangxiong1.callback);
},
- callback() {
- player.gain(card, "gain2");
+ async callback(event, trigger, player) {
+ await player.gain(event.card, "gain2");
player.addTempSkill("shuangxiong2");
player.markAuto("shuangxiong2", [event.judgeResult.color]);
},
@@ -6036,17 +5975,17 @@ const skills = {
return player.hasCard(card => lib.skill.shuangxiong2.filterCard(card, player), "hs");
},
filterCard(card, player) {
- var color = get.color(card),
+ const color = get.color(card),
colors = player.getStorage("shuangxiong2");
- for (var i of colors) {
+ for (const i of colors) {
if (color != i) return true;
}
return false;
},
prompt() {
- var colors = _status.event.player.getStorage("shuangxiong2");
- var str = "将一张颜色";
- for (var i = 0; i < colors.length; i++) {
+ const colors = _status.event.player.getStorage("shuangxiong2");
+ let str = "将一张颜色";
+ for (let i = 0; i < colors.length; i++) {
if (i > 0) str += "或";
str += "不为";
str += get.translation(colors[i]);
@@ -6055,9 +5994,9 @@ const skills = {
return str;
},
check(card) {
- var player = _status.event.player;
- var raw = player.getUseValue(card, null, true);
- var eff = player.getUseValue(get.autoViewAs({ name: "juedou" }, [card]));
+ const player = _status.event.player;
+ const raw = player.getUseValue(card, null, true);
+ const eff = player.getUseValue(get.autoViewAs({ name: "juedou" }, [card]));
return eff - raw;
},
ai: { order: 7 },
@@ -6071,8 +6010,8 @@ const skills = {
if (ui.selected.cards.length) {
return get.suit(card) == get.suit(ui.selected.cards[0]);
}
- var cards = player.getCards("hs");
- for (var i = 0; i < cards.length; i++) {
+ const cards = player.getCards("hs");
+ for (let i = 0; i < cards.length; i++) {
if (card != cards[i]) {
if (get.suit(card) == get.suit(cards[i])) return true;
}
@@ -6082,13 +6021,13 @@ const skills = {
selectCard: 2,
complexCard: true,
check(card) {
- var player = _status.event.player;
- var targets = game.filterPlayer(function (current) {
+ const player = _status.event.player;
+ const targets = game.filterPlayer(function (current) {
return player.canUse("wanjian", current);
});
- var num = 0;
- for (var i = 0; i < targets.length; i++) {
- var eff = get.sgn(get.effect(targets[i], { name: "wanjian" }, player, player));
+ let num = 0;
+ for (let i = 0; i < targets.length; i++) {
+ let eff = get.sgn(get.effect(targets[i], { name: "wanjian" }, player, player));
if (targets[i].hp == 1) {
eff *= 1.5;
}
@@ -6124,7 +6063,7 @@ const skills = {
player.countCards("h") > player.hp
);
},
- content() {},
+ async content() {},
mod: {
maxHandcard(player, num) {
if (player.hasZhuSkill("xueyi")) {
@@ -6152,8 +6091,8 @@ const skills = {
return get.attitude(player, event.target) < 0;
},
logTarget: "target",
- content() {
- player.discardPlayerCard("he", trigger.target, true);
+ async content(event, trigger, player) {
+ await player.discardPlayerCard("he", trigger.target, true);
},
},
jiewei: {
@@ -6161,57 +6100,50 @@ const skills = {
//direct:true,
frequent: true,
audio: "xinjiewei",
- content() {
- "step 0";
- player.draw();
- player.chooseToUse(function (card) {
+ async content(event, trigger, player) {
+ await player.draw();
+ const { result } = await player.chooseToUse(function (card) {
if (!lib.filter.cardEnabled(card, _status.event.player, _status.event)) {
return false;
}
- var type = get.type(card, "trick");
+ const type = get.type(card, "trick");
return type == "trick" || type == "equip";
}, "是否使用一张锦囊牌或装备牌?");
- "step 1";
- if (result.bool) {
- var type = get.type(result.card || result.cards[0]);
- if (
- game.hasPlayer(function (current) {
- if (type == "equip") {
- return current.countCards("e");
- } else {
- return current.countCards("j");
- }
- })
- ) {
- var next = player.chooseTarget("是否弃置场上的一张" + get.translation(type) + "牌?", function (card, player, target) {
- if (_status.event.type == "equip") {
- return target.countCards("e") > 0;
- } else {
- return target.countCards("j") > 0;
- }
- });
- next.set("ai", function (target) {
- if (type == "equip") {
- return -get.attitude(player, target);
- } else {
- return get.attitude(player, target);
- }
- });
- next.set("type", type);
- event.type = type;
+ if (!result.bool) return;
+ const type = get.type(result.card || result.cards[0]);
+ if (
+ !game.hasPlayer(function (current) {
+ if (type == "equip") {
+ return current.countCards("e");
+ } else {
+ return current.countCards("j");
+ }
+ })
+ )
+ return;
+ const next = player.chooseTarget("是否弃置场上的一张" + get.translation(type) + "牌?", function (card, player, target) {
+ if (_status.event.type == "equip") {
+ return target.countCards("e") > 0;
} else {
- event.finish();
+ return target.countCards("j") > 0;
}
- } else {
- event.finish();
- }
- "step 2";
- if (event.type && result.bool && result.targets && result.targets.length) {
- player.line(result.targets, "green");
- if (event.type == "equip") {
+ });
+ next.set("ai", function (target) {
+ if (type == "equip") {
+ return -get.attitude(player, target);
+ } else {
+ return get.attitude(player, target);
+ }
+ });
+ next.set("type", type);
+ event.type = type;
+ const result2 = await next.forResult();
+ if (type && result2.bool && result2.targets && result2.targets.length) {
+ player.line(result2.targets, "green");
+ if (type == "equip") {
player.discardPlayerCard(result.targets[0], "e", true);
} else {
- player.discardPlayerCard(result.targets[0], "j", true);
+ player.discardPlayerCard(result2.targets[0], "j", true);
}
}
},
@@ -6223,36 +6155,34 @@ const skills = {
filter(event, player) {
return event.card.name == "shan";
},
- direct: true,
- content() {
- "step 0";
- player.chooseTarget(get.prompt2("releiji"), function (card, player, target) {
+ line: "thunder",
+ async cost(event, trigger, player) {
+ const next = player.chooseTarget(get.prompt2("releiji"), function (card, player, target) {
return target != player;
- }).ai = function (target) {
+ });
+ next.ai = function (target) {
if (target.hasSkill("hongyan")) return 0;
return get.damageEffect(target, _status.event.player, _status.event.player, "thunder");
};
- "step 1";
- if (result.bool) {
- player.logSkill("releiji", result.targets, "thunder");
- event.target = result.targets[0];
- event.target.judge(function (card) {
- var suit = get.suit(card);
- if (suit == "spade") return -4;
- if (suit == "club") return -2;
- return 0;
- }).judge2 = function (result) {
- return result.bool == false ? true : false;
- };
- } else {
- event.finish();
- }
- "step 2";
- if (result.suit == "club") {
- player.recover();
- event.target.damage("thunder");
- } else if (result.suit == "spade") {
- event.target.damage(2, "thunder");
+ event.result = await next.forResult();
+ },
+ async content(event, trigger, player) {
+ const [target] = event.targets;
+ const next = target.judge(function (card) {
+ const suit = get.suit(card);
+ if (suit == "spade") return -4;
+ if (suit == "club") return -2;
+ return 0;
+ });
+ next.judge2 = function (result) {
+ return result.bool == false; // ? true : false; 喵?
+ };
+ const { suit } = await next.forResult();
+ if (suit == "club") {
+ await player.recover();
+ await target.damage("thunder");
+ } else if (suit == "spade") {
+ await target.damage(2, "thunder");
}
},
ai: {
@@ -6337,10 +6267,8 @@ const skills = {
dc_xiahouba: "shensu1_xiahouba",
},
trigger: { player: "phaseJudgeBefore" },
- direct: true,
- content() {
- "step 0";
- player
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseTarget(get.prompt("shensu"), "跳过判定阶段和摸牌阶段,视为对一名其他角色使用一张【杀】", function (card, player, target) {
if (player == target) return false;
return player.canUse({ name: "sha" }, target, false);
@@ -6350,14 +6278,13 @@ const skills = {
if (!_status.event.check) return 0;
return get.effect(target, { name: "sha" }, _status.event.player);
})
- .setHiddenSkill("shensu1");
- "step 1";
- if (result.bool) {
- player.logSkill("shensu1", result.targets);
- player.useCard({ name: "sha", isCard: true }, result.targets[0], false);
- trigger.cancel();
- player.skip("phaseDraw");
- }
+ .setHiddenSkill("shensu1")
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.cancel();
+ player.skip("phaseDraw");
+ await player.useCard({ name: "sha", isCard: true }, event.targets[0], false);
},
},
shensu2: {
@@ -6367,7 +6294,6 @@ const skills = {
dc_xiahouba: "shensu1_xiahouba",
},
trigger: { player: "phaseUseBefore" },
- direct: true,
filter(event, player) {
return (
player.countCards("he", function (card) {
@@ -6376,9 +6302,8 @@ const skills = {
}) > 0
);
},
- content() {
- "step 0";
- player
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseCardTarget({
prompt: get.prompt("shensu"),
prompt2: "弃置一张装备牌并跳过出牌阶段,视为对一名其他角色使用一张【杀】",
@@ -6404,14 +6329,13 @@ const skills = {
}) >
player.hp - 1,
})
- .setHiddenSkill("shensu2");
- "step 1";
- if (result.bool) {
- player.logSkill("shensu2", result.targets);
- player.discard(result.cards[0]);
- player.useCard({ name: "sha", isCard: true }, result.targets[0], false);
- trigger.cancel();
- }
+ .setHiddenSkill("shensu2")
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.cancel();
+ await player.discard(event.cards[0]);
+ await player.useCard({ name: "sha", isCard: true }, event.targets[0], false);
},
},
shensu4: {
@@ -6421,11 +6345,9 @@ const skills = {
dc_xiahouba: "shensu1_xiahouba",
},
trigger: { player: "phaseDiscardBefore" },
- direct: true,
- content() {
- "step 0";
- var check = player.needsToDiscard() || player.isTurnedOver() || (player.hasSkill("shebian") && player.canMoveCard(true, true));
- player
+ async cost(event, trigger, player) {
+ const check = player.needsToDiscard() || player.isTurnedOver() || (player.hasSkill("shebian") && player.canMoveCard(true, true));
+ event.result = await player
.chooseTarget(get.prompt("shensu"), "跳过弃牌阶段并将武将牌翻面,视为对一名其他角色使用一张【杀】", function (card, player, target) {
if (player == target) return false;
return player.canUse({ name: "sha" }, target, false);
@@ -6434,14 +6356,13 @@ const skills = {
.set("ai", function (target) {
if (!_status.event.check) return 0;
return get.effect(target, { name: "sha" }, _status.event.player, _status.event.player);
- });
- "step 1";
- if (result.bool) {
- player.logSkill("shensu4", result.targets);
- player.turnOver();
- player.useCard({ name: "sha", isCard: true }, result.targets[0], false);
- trigger.cancel();
- }
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.cancel();
+ await player.turnOver();
+ await player.useCard({ name: "sha", isCard: true }, event.targets[0], false);
},
},
jushou: {
@@ -6450,9 +6371,9 @@ const skills = {
check(event, player) {
return event.player.hp + player.countCards("h") < 4;
},
- content() {
- player.draw(3);
- player.turnOver();
+ async content(event, trigger, player) {
+ await player.draw(3);
+ await player.turnOver();
},
ai: {
effect: {
@@ -6468,9 +6389,9 @@ const skills = {
check(event, player) {
return event.player.hp + player.countCards("h") < 4;
},
- content() {
- player.draw();
- player.turnOver();
+ async content(event, trigger, player) {
+ await player.draw();
+ await player.turnOver();
},
ai: {
effect: {
@@ -6491,11 +6412,11 @@ const skills = {
logTarget: "target",
filter(event, player) {
if (event.card.name != "sha") return false;
- var length = event.target.countCards("h");
+ const length = event.target.countCards("h");
return length >= player.hp || length <= player.getAttackRange();
},
preHidden: true,
- content() {
+ async content(event, trigger, player) {
trigger.getParent().directHit.push(trigger.target);
},
locked: false,
@@ -6508,7 +6429,7 @@ const skills = {
directHit_ai: true,
skillTagFilter(player, tag, arg) {
if (get.attitude(player, arg.target) > 0 || arg.card.name != "sha") return false;
- var length = arg.target.countCards("h");
+ const length = arg.target.countCards("h");
return length >= player.hp || length <= player.getAttackRange();
},
},
@@ -6521,8 +6442,8 @@ const skills = {
filter(event, player) {
return event.kuangguCheck && player.isDamaged();
},
- content() {
- player.recover(trigger.num);
+ async content(event, trigger, player) {
+ await player.recover(trigger.num);
},
group: "kuanggu_check",
subSkill: {
@@ -6544,64 +6465,62 @@ const skills = {
audio: 2,
audioname: ["daxiaoqiao", "re_xiaoqiao", "ol_xiaoqiao"],
trigger: { player: "damageBegin3" },
- direct: true,
filter(event, player) {
return player.countCards("h", { suit: "heart" }) > 0 && event.num > 0;
},
- content() {
- "step 0";
- player.chooseCardTarget({
- filterCard(card, player) {
- return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player);
- },
- filterTarget(card, player, target) {
- return player != target;
- },
- ai1(card) {
- return 10 - get.value(card);
- },
- ai2(target) {
- var att = get.attitude(_status.event.player, target);
- var trigger = _status.event.getTrigger();
- var da = 0;
- if (_status.event.player.hp == 1) {
- da = 10;
- }
- if (trigger.num > 1) {
- if (target.maxHp > 5 && target.hp > 1) return -att / 10 + da;
- return -att + da;
- }
- var eff = get.damageEffect(target, trigger.source, target, trigger.nature);
- if (att == 0) return 0.1 + da;
- if (eff >= 0 && trigger.num == 1) {
- return att + da;
- }
- if (target.hp == target.maxHp) return -att + da;
- if (target.hp == 1) {
- if (target.maxHp <= 4 && !target.hasSkillTag("maixie")) {
- if (target.maxHp <= 3) {
- return -att + da;
- }
- return -att / 2 + da;
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseCardTarget({
+ filterCard(card, player) {
+ return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player);
+ },
+ filterTarget(card, player, target) {
+ return player != target;
+ },
+ ai1(card) {
+ return 10 - get.value(card);
+ },
+ ai2(target) {
+ const att = get.attitude(_status.event.player, target);
+ const trigger = _status.event.getTrigger();
+ let da = 0;
+ if (_status.event.player.hp == 1) {
+ da = 10;
}
- return da;
- }
- if (target.hp == target.maxHp - 1) {
- if (target.hp > 2 || target.hasSkillTag("maixie")) return att / 5 + da;
- if (att > 0) return 0.02 + da;
- return 0.05 + da;
- }
- return att / 2 + da;
- },
- prompt: get.prompt2("tianxiang"),
- });
- "step 1";
- if (result.bool) {
- player.logSkill(event.name, result.targets);
- trigger.player = result.targets[0];
- trigger.player.addSkill("tianxiang2");
- player.discard(result.cards[0]);
- }
+ if (trigger.num > 1) {
+ if (target.maxHp > 5 && target.hp > 1) return -att / 10 + da;
+ return -att + da;
+ }
+ const eff = get.damageEffect(target, trigger.source, target, trigger.nature);
+ if (att == 0) return 0.1 + da;
+ if (eff >= 0 && trigger.num == 1) {
+ return att + da;
+ }
+ if (target.hp == target.maxHp) return -att + da;
+ if (target.hp == 1) {
+ if (target.maxHp <= 4 && !target.hasSkillTag("maixie")) {
+ if (target.maxHp <= 3) {
+ return -att + da;
+ }
+ return -att / 2 + da;
+ }
+ return da;
+ }
+ if (target.hp == target.maxHp - 1) {
+ if (target.hp > 2 || target.hasSkillTag("maixie")) return att / 5 + da;
+ if (att > 0) return 0.02 + da;
+ return 0.05 + da;
+ }
+ return att / 2 + da;
+ },
+ prompt: get.prompt2("tianxiang"),
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.player = event.targets[0];
+ trigger.player.addSkill("tianxiang2");
+ await player.discard(event.cards[0]);
},
ai: {
maixie_defend: true,
@@ -6623,17 +6542,16 @@ const skills = {
audio: false,
vanish: true,
charlotte: true,
- content() {
- if (player.getDamagedHp()) player.draw(player.getDamagedHp());
+ async content(event, trigger, player) {
player.removeSkill("tianxiang2");
player.popup("tianxiang");
+ if (player.getDamagedHp()) await player.draw(player.getDamagedHp());
},
},
retianxiang: {
audio: "tianxiang",
audioname: ["daxiaoqiao", "re_xiaoqiao", "ol_xiaoqiao"],
trigger: { player: "damageBegin4" },
- direct: true,
preHidden: true,
filter(event, player) {
return (
@@ -6642,9 +6560,8 @@ const skills = {
}) > 0 && event.num > 0
);
},
- content() {
- "step 0";
- player
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseCardTarget({
filterCard(card, player) {
return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player);
@@ -6656,13 +6573,13 @@ const skills = {
return 10 - get.value(card);
},
ai2(target) {
- var att = get.attitude(_status.event.player, target);
- var trigger = _status.event.getTrigger();
- var da = 0;
+ const att = get.attitude(_status.event.player, target);
+ const trigger = _status.event.getTrigger();
+ let da = 0;
if (_status.event.player.hp == 1) {
da = 10;
}
- var eff = get.damageEffect(target, trigger.source, target);
+ const eff = get.damageEffect(target, trigger.source, target);
if (att == 0) return 0.1 + da;
if (eff >= 0 && att > 0) {
return att + da;
@@ -6676,47 +6593,40 @@ const skills = {
prompt: get.prompt("retianxiang"),
prompt2: lib.translate.retianxiang_info,
})
- .setHiddenSkill(event.name);
- "step 1";
- if (result.bool) {
- player.discard(result.cards);
- var target = result.targets[0];
- player
- .chooseControlList(
- true,
- function (event, player) {
- var target = _status.event.target;
- var att = get.attitude(player, target);
- if (target.hasSkillTag("maihp")) att = -att;
- if (att > 0) {
- return 0;
- } else {
- return 1;
- }
- },
- ["令" + get.translation(target) + "受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)", "令" + get.translation(target) + "失去1点体力,然后获得" + get.translation(result.cards)]
- )
- .set("target", target);
- player.logSkill(event.name, target);
- trigger.cancel();
- event.target = target;
- event.card = result.cards[0];
+ .setHiddenSkill(event.name)
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const [target] = event.targets;
+ const [card] = event.cards;
+ trigger.cancel();
+ await player.discard(event.cards);
+ const { result } = await player
+ .chooseControlList(
+ true,
+ function (event, player) {
+ const target = _status.event.target;
+ let att = get.attitude(player, target);
+ if (target.hasSkillTag("maihp")) att = -att;
+ if (att > 0) {
+ return 0;
+ } else {
+ return 1;
+ }
+ },
+ ["令" + get.translation(target) + "受到伤害来源对其造成的1点伤害,然后摸X张牌(X为其已损失体力值且至多为5)", "令" + get.translation(target) + "失去1点体力,然后获得" + get.translation(event.cards)]
+ )
+ .set("target", target);
+ if (typeof result.index != "number") return;
+ if (result.index) {
+ event.related = target.loseHp();
} else {
- event.finish();
+ event.related = target.damage(trigger.source || "nosource", "nocard");
}
- "step 2";
- if (typeof result.index == "number") {
- event.index = result.index;
- if (result.index) {
- event.related = event.target.loseHp();
- } else {
- event.related = event.target.damage(trigger.source || "nosource", "nocard");
- }
- } else event.finish();
- "step 3";
+ await event.related;
//if(event.related.cancelled||target.isDead()) return;
- if (event.index && card.isInPile()) target.gain(card, "gain2");
- else if (target.getDamagedHp()) target.draw(Math.min(5, target.getDamagedHp()));
+ if (result.index && card.isInPile()) await target.gain(card, "gain2");
+ else if (target.getDamagedHp()) await target.draw(Math.min(5, target.getDamagedHp()));
},
ai: {
maixie_defend: true,
@@ -6736,14 +6646,12 @@ const skills = {
return event.type == "retianxiang";
},
vanish: true,
- content() {
- "step 0";
- player.gain(player.storage.retianxiang3, "gain2");
- "step 1";
+ async content(event, trigger, player) {
+ await player.gain(player.storage.retianxiang3, "gain2");
player.removeSkill("retianxiang3");
},
onremove(player) {
- var card = player.storage.retianxiang3;
+ const card = player.storage.retianxiang3;
if (get.position(card) == "s") {
game.cardsDiscard(card);
}
@@ -6758,9 +6666,9 @@ const skills = {
return event.type == "retianxiang";
},
vanish: true,
- content() {
+ async content(event, trigger, player) {
if (player.isDamaged()) {
- player.draw(player.getDamagedHp());
+ await player.draw(player.getDamagedHp());
}
player.removeSkill("retianxiang2");
},
@@ -6768,68 +6676,64 @@ const skills = {
xintianxiang: {
audio: "tianxiang",
trigger: { player: "damageBefore" },
- direct: true,
filter(event, player) {
return player.countCards("he", { suit: "heart" }) > 0 && event.num > 0 && !player.hasSkill("xintianxiang3");
},
- content() {
- "step 0";
- player.chooseCardTarget({
- filterCard(card, player) {
- return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player);
- },
- filterTarget(card, player, target) {
- return player != target;
- },
- position: "he",
- ai1(card) {
- return 10 - get.value(card);
- },
- ai2(target) {
- var att = get.attitude(_status.event.player, target);
- var trigger = _status.event.getTrigger();
- var da = 0;
- if (_status.event.player.hp == 1) {
- da = 10;
- }
- if (trigger.num > 1) {
- if (target.maxHp > 5 && target.hp > 1) return -att / 10 + da;
- return -att + da;
- }
- var eff = get.damageEffect(target, trigger.source, target, trigger.nature);
- if (att == 0) return 0.1 + da;
- if (eff >= 0 && trigger.num == 1) {
- return att + da;
- }
- if (target.hp == target.maxHp) return -att + da;
- if (target.hp == 1) {
- if (target.maxHp <= 4 && !target.hasSkillTag("maixie")) {
- if (target.maxHp <= 3) {
- return -att + da;
- }
- return -att / 2 + da;
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseCardTarget({
+ filterCard(card, player) {
+ return get.suit(card) == "heart" && lib.filter.cardDiscardable(card, player);
+ },
+ filterTarget(card, player, target) {
+ return player != target;
+ },
+ position: "he",
+ ai1(card) {
+ return 10 - get.value(card);
+ },
+ ai2(target) {
+ const att = get.attitude(_status.event.player, target);
+ const trigger = _status.event.getTrigger();
+ let da = 0;
+ if (_status.event.player.hp == 1) {
+ da = 10;
}
- return da;
- }
- if (target.hp == target.maxHp - 1) {
- if (target.hp > 2 || target.hasSkillTag("maixie")) return att / 5 + da;
- if (att > 0) return 0.02 + da;
- return 0.05 + da;
- }
- return att / 2 + da;
- },
- prompt: get.prompt2("xintianxiang"),
- });
- "step 1";
- if (result.bool) {
- player.logSkill(event.name, result.targets);
- trigger.player = result.targets[0];
- trigger.player.addSkill("xintianxiang2");
- trigger.player.storage.xintianxiang = player;
- player.discard(result.cards[0]);
- } else {
- event.finish();
- }
+ if (trigger.num > 1) {
+ if (target.maxHp > 5 && target.hp > 1) return -att / 10 + da;
+ return -att + da;
+ }
+ const eff = get.damageEffect(target, trigger.source, target, trigger.nature);
+ if (att == 0) return 0.1 + da;
+ if (eff >= 0 && trigger.num == 1) {
+ return att + da;
+ }
+ if (target.hp == target.maxHp) return -att + da;
+ if (target.hp == 1) {
+ if (target.maxHp <= 4 && !target.hasSkillTag("maixie")) {
+ if (target.maxHp <= 3) {
+ return -att + da;
+ }
+ return -att / 2 + da;
+ }
+ return da;
+ }
+ if (target.hp == target.maxHp - 1) {
+ if (target.hp > 2 || target.hasSkillTag("maixie")) return att / 5 + da;
+ if (att > 0) return 0.02 + da;
+ return 0.05 + da;
+ }
+ return att / 2 + da;
+ },
+ prompt: get.prompt2("xintianxiang"),
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ trigger.player = event.targets[0];
+ trigger.player.addSkill("xintianxiang2");
+ trigger.player.storage.xintianxiang = player;
+ await player.discard(event.cards[0]);
},
ai: {
maixie_defend: true,
@@ -6847,18 +6751,14 @@ const skills = {
popup: false,
audio: false,
vanish: true,
- content() {
- "step 0";
- var source = player.storage.xintianxiang;
- if (source.isDead()) {
- event.finish();
- return;
- }
- var num = player.maxHp - player.hp || 0;
- var str1 = "令" + get.translation(player) + "摸" + get.cnNumber(num) + "张牌";
- var str2 = "令" + get.translation(player) + "防止造成和受到的所有伤害且天香失效直到你下一回合开始";
- var att = get.attitude(source, player);
- var choice = "选项一";
+ async content(event, trigger, player) {
+ const source = player.storage.xintianxiang;
+ if (source.isDead()) return;
+ const num = player.maxHp - player.hp || 0;
+ const str1 = "令" + get.translation(player) + "摸" + get.cnNumber(num) + "张牌";
+ const str2 = "令" + get.translation(player) + "防止造成和受到的所有伤害且天香失效直到你下一回合开始";
+ const att = get.attitude(source, player);
+ let choice = "选项一";
if (att < 0) {
if (num >= 2) {
choice = "选项二";
@@ -6868,17 +6768,15 @@ const skills = {
choice = "选项二";
}
}
- source
+ const control = await source
.chooseControl(function () {
return _status.event.choice;
})
.set("choiceList", [str1, str2])
- .set("choice", choice);
- "step 1";
- if (result.control == "选项一") {
- if (player.isDamaged()) {
- player.draw(player.maxHp - player.hp);
- }
+ .set("choice", choice)
+ .forResultControl();
+ if (control == "选项一") {
+ if (player.isDamaged()) await player.draw(player.maxHp - player.hp);
} else {
player.storage.xintianxiang.addSkill("xintianxiang3");
player.storage.xintianxiang.storage.xintianxiang3 = player;
@@ -6891,7 +6789,7 @@ const skills = {
xintianxiang3: {
trigger: { player: ["phaseZhunbeiBegin", "dieBegin"] },
silent: true,
- content() {
+ async content(event, trigger, player) {
if (player.storage.xintianxiang3) {
player.storage.xintianxiang3.removeSkill("xintianxiang4");
delete player.storage.xintianxiang3;
@@ -6907,7 +6805,7 @@ const skills = {
content: "防止造成和受到的一切伤害",
},
priority: 15,
- content() {
+ async content(event, trigger, player) {
trigger.cancel();
},
ai: {
@@ -6946,25 +6844,22 @@ const skills = {
},
},
trigger: { global: "judge" },
- direct: true,
filter(event, player) {
if (event.fixedResult && event.fixedResult.suit) return event.fixedResult.suit == "heart";
return get.suit(event.player.judging[0], event.player) == "heart";
},
- content() {
- "step 0";
- var str = "红颜:" + get.translation(trigger.player) + "的" + (trigger.judgestr || "") + "判定为" + get.translation(trigger.player.judging[0]) + ",请将其改为一种花色";
- player
+ async cost(event, trigger, player) {
+ const str = "红颜:" + get.translation(trigger.player) + "的" + (trigger.judgestr || "") + "判定为" + get.translation(trigger.player.judging[0]) + ",请将其改为一种花色";
+ const control = await player
.chooseControl("spade", "heart", "diamond", "club")
.set("prompt", str)
.set("ai", function () {
- var judging = _status.event.judging;
- var trigger = _status.event.getTrigger();
- var res1 = trigger.judge(judging);
- var list = lib.suit.slice(0);
- var attitude = get.attitude(player, trigger.player);
+ const judging = _status.event.judging;
+ const trigger = _status.event.getTrigger();
+ const list = lib.suit.slice(0);
+ const attitude = get.attitude(player, trigger.player);
if (attitude == 0) return 0;
- var getj = function (suit) {
+ const getj = function (suit) {
return trigger.judge({
name: get.name(judging),
nature: get.nature(judging),
@@ -6977,16 +6872,21 @@ const skills = {
});
return list[0];
})
- .set("judging", trigger.player.judging[0]);
- "step 1";
- if (result.control != "cancel2") {
- player.addExpose(0.25);
- player.popup(result.control);
- game.log(player, "将判定结果改为了", "#y" + get.translation(result.control + 2));
- if (!trigger.fixedResult) trigger.fixedResult = {};
- trigger.fixedResult.suit = result.control;
- trigger.fixedResult.color = get.color({ suit: result.control });
- }
+ .set("judging", trigger.player.judging[0])
+ .forResultControl();
+ event.result = {
+ bool: control != "cancel2",
+ cost_data: control,
+ };
+ },
+ async content(event, trigger, player) {
+ const control = event.cost_data;
+ player.addExpose(0.25);
+ player.popup(control);
+ game.log(player, "将判定结果改为了", "#y" + get.translation(control + 2));
+ if (!trigger.fixedResult) trigger.fixedResult = {};
+ trigger.fixedResult.suit = control;
+ trigger.fixedResult.color = get.color({ suit: control });
},
ai: {
rejudge: true,
@@ -7011,7 +6911,7 @@ const skills = {
frequent: true,
ondisable: true,
onremove(player, skill) {
- var cards = player.getExpansions(skill);
+ const cards = player.getExpansions(skill);
if (cards.length) {
//delete player.nodying;
player.loseToDiscardpile(cards);
@@ -7020,9 +6920,9 @@ const skills = {
},
process(player) {
//delete player.nodying;
- var nums = [];
- var cards = player.getExpansions("gzbuqu");
- for (var i = 0; i < cards.length; i++) {
+ const nums = [];
+ const cards = player.getExpansions("gzbuqu");
+ for (let i = 0; i < cards.length; i++) {
if (nums.includes(get.number(cards[i]))) {
return false;
} else {
@@ -7040,35 +6940,31 @@ const skills = {
},
forced: true,
popup: false,
- content() {
- "step 0";
- event.count = trigger.num;
- "step 1";
- event.count--;
- var cards = player.getExpansions("gzbuqu"),
- count = cards.length;
- if (count > 0 && player.hp + count > 1) {
- if (count == 1) event._result = { links: cards };
- else
- player.chooseCardButton("不屈:移去一张“创”", true, cards).set("ai", function (button) {
- var buttons = get.selectableButtons();
- for (var i = 0; i < buttons.length; i++) {
- if (buttons[i] != button && get.number(buttons[i].link) == get.number(button.link) && !ui.selected.buttons.includes(buttons[i])) {
- return 1;
+ async content(event, trigger, player) {
+ for (let i = trigger.num; i > 0; i--) {
+ let cards = player.getExpansions("gzbuqu");
+ const count = cards.length;
+ if (count <= 0 || player.hp + count <= 1) return;
+ if (count > 1) {
+ cards = await player
+ .chooseCardButton("不屈:移去一张“创”", true, cards)
+ .set("ai", function (button) {
+ const buttons = get.selectableButtons();
+ for (let i = 0; i < buttons.length; i++) {
+ if (buttons[i] != button && get.number(buttons[i].link) == get.number(button.link) && !ui.selected.buttons.includes(buttons[i])) {
+ return 1;
+ }
}
- }
- return 0;
- });
- } else event.finish();
- "step 2";
- var cards = result.links;
- player.loseToDiscardpile(cards);
- if (event.count) event.goto(1);
- "step 3";
+ return 0;
+ })
+ .forResultLinks();
+ }
+ await player.loseToDiscardpile(cards);
+ }
if (lib.skill.gzbuqu.process(player)) {
if (player.isDying()) {
- var evt = event,
- histories = [evt];
+ const histories = [evt];
+ let evt = event;
while (true) {
evt = event.getParent("dying");
if (!evt || evt.name != "dying" || histories.includes(evt)) break;
@@ -7080,15 +6976,14 @@ const skills = {
},
},
},
- content() {
- "step 0";
- var num = -trigger.num - Math.max(player.hp - trigger.num, 1) + 1;
- player.addToExpansion(get.cards(num), "gain2").gaintag.add("gzbuqu");
- "step 1";
- player.showCards(get.translation(player) + "的不屈牌", player.getExpansions("gzbuqu"));
- "step 2";
+ async content(event, trigger, player) {
+ const num = -trigger.num - Math.max(player.hp - trigger.num, 1) + 1;
+ const next = player.addToExpansion(get.cards(num), "gain2");
+ next.gaintag.add("gzbuqu");
+ await next;
+ await player.showCards(get.translation(player) + "的不屈牌", player.getExpansions("gzbuqu"));
if (lib.skill.gzbuqu.process(player)) {
- var evt = trigger.getParent();
+ const evt = trigger.getParent();
if (evt.name == "damage" || evt.name == "loseHp") evt.nodying = true;
}
},
@@ -7105,26 +7000,25 @@ const skills = {
filter(event, player) {
return event.type == "dying" && player.isDying() && event.dying == player && !event.getParent()._buqu;
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
trigger.getParent()._buqu = true;
- var card = get.cards()[0];
- event.card = card;
- player.addToExpansion(card, "gain2").gaintag.add("buqu");
- "step 1";
- var cards = player.getExpansions("buqu"),
+ const [card] = get.cards();
+ const next = player.addToExpansion(card, "gain2");
+ next.gaintag.add("buqu");
+ await next;
+ const cards = player.getExpansions("buqu"),
num = get.number(card);
player.showCards(cards, "不屈");
- for (var i = 0; i < cards.length; i++) {
+ for (let i = 0; i < cards.length; i++) {
if (cards[i] != card && get.number(cards[i]) == num) {
- player.loseToDiscardpile(card);
+ await player.loseToDiscardpile(card);
return;
}
}
trigger.cancel();
trigger.result = { bool: true };
if (player.hp <= 0) {
- player.recover(1 - player.hp);
+ await player.recover(1 - player.hp);
}
},
mod: {
@@ -7149,7 +7043,6 @@ const skills = {
trigger: {
global: ["gainAfter", "loseAfter", "loseAsyncAfter"],
},
- direct: true,
filter(event, player) {
if (event.name == "lose") {
if (event.type != "discard" || !event.player.isIn()) return false;
@@ -7158,23 +7051,23 @@ const skills = {
return true;
} else if (event.name == "gain") {
if (event.giver || event.getParent().name == "gift") return false;
- var cards = event.getg(event.player);
+ const cards = event.getg(event.player);
if (!cards.length) return false;
return game.hasPlayer(function (current) {
if (current == event.player) return false;
- var hs = event.getl(current).hs;
- for (var i of hs) {
+ const hs = event.getl(current).hs;
+ for (const i of hs) {
if (cards.includes(i)) return true;
}
return false;
});
} else if (event.type == "gain") {
if (event.giver || !event.player || !event.player.isIn()) return false;
- var hs = event.getl(event.player);
+ const hs = event.getl(event.player);
return game.hasPlayer(function (current) {
if (current == event.player) return false;
- var cards = event.getg(current);
- for (var i of cards) {
+ const cards = event.getg(current);
+ for (const i of cards) {
if (hs.includes(i)) return true;
}
});
@@ -7186,53 +7079,43 @@ const skills = {
}
return false;
},
- content() {
- "step 0";
- var targets = [];
- if (trigger.name == "gain") {
- var cards = trigger.getg(trigger.player);
+ getIndex(event) {
+ const targets = [];
+ if (event.name == "gain") {
+ const cards = event.getg(event.player);
targets.addArray(
game.filterPlayer(function (current) {
- if (current == trigger.player) return false;
- var hs = trigger.getl(current).hs;
- for (var i of hs) {
+ if (current == event.player) return false;
+ const hs = event.getl(current).hs;
+ for (const i of hs) {
if (cards.includes(i)) return true;
}
return false;
})
);
- } else if (trigger.name == "loseAsync" && trigger.type == "discard") {
+ } else if (event.name == "loseAsync" && event.type == "discard") {
targets.addArray(
game.filterPlayer(function (current) {
- return current != trigger.discarder && trigger.getl(current).hs.length > 0;
+ return current != event.discarder && event.getl(current).hs.length > 0;
})
);
- } else targets.push(trigger.player);
- event.targets = targets.sortBySeat();
- if (!event.targets.length) event.finish();
- "step 1";
- var target = targets.shift();
- event.target = target;
- if (target.isIn())
- player.chooseBool(get.prompt("fenji", target), "失去1点体力,令该角色摸两张牌").set("ai", function () {
- var evt = _status.event.getParent();
+ } else targets.push(event.player);
+ return targets;
+ },
+ async cost(event, trigger, player) {
+ const target = event.indexedData;
+ event.result = await player
+ .chooseBool(get.prompt("fenji", target), "失去1点体力,令该角色摸两张牌")
+ .set("ai", function () {
+ const evt = _status.event.getParent();
return get.attitude(evt.player, evt.target) > 4;
- });
- else {
- if (targets.length > 0) event.goto(1);
- else event.finish();
- }
- "step 2";
- if (result.bool) {
- player.logSkill("fenji", target);
- player.loseHp();
- } else {
- if (targets.length > 0) event.goto(1);
- else event.finish();
- }
- "step 3";
- target.draw(2);
- if (targets.length > 0) event.goto(1);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const target = event.indexedData;
+ await player.loseHp();
+ await target.draw(2);
},
},
new_fenji: {
@@ -7248,10 +7131,10 @@ const skills = {
check(event, player) {
return get.attitude(player, event.player) > 2;
},
- content() {
+ async content(event, trigger, player) {
player.line(trigger.player, "green");
- trigger.player.draw(2);
- player.loseHp();
+ await trigger.player.draw(2);
+ await player.loseHp();
},
},
leiji: {
@@ -7260,30 +7143,28 @@ const skills = {
filter(event, player) {
return event.card.name == "shan";
},
- direct: true,
preHidden: true,
- content() {
- "step 0";
- player.chooseTarget(get.prompt2("leiji")).setHiddenSkill(event.name).ai = function (target) {
+ line: "thunder",
+ async cost(event, trigger, player) {
+ const next = player.chooseTarget(get.prompt2("leiji")).setHiddenSkill(event.name);
+ next.ai = function (target) {
if (target.hasSkill("hongyan")) return 0;
return get.damageEffect(target, _status.event.player, _status.event.player, "thunder");
};
- "step 1";
- if (result.bool) {
- player.logSkill("leiji", result.targets, "thunder");
- event.target = result.targets[0];
- event.target.judge(function (card) {
- if (get.suit(card) == "spade") return -4;
- return 0;
- }).judge2 = function (result) {
- return result.bool == false ? true : false;
- };
- } else {
- event.finish();
- }
- "step 2";
- if (result.bool == false) {
- event.target.damage(2, "thunder");
+ event.result = await next.forResult();
+ },
+ async content(event, trigger, player) {
+ const [target] = event.targets;
+ const next = target.judge(function (card) {
+ if (get.suit(card) == "spade") return -4;
+ return 0;
+ });
+ next.judge2 = function (result) {
+ return result.bool == false ? true : false;
+ };
+ const bool = await next.forResultBool();
+ if (bool == false) {
+ await target.damage(2, "thunder");
}
},
ai: {
@@ -7340,25 +7221,23 @@ const skills = {
filter(event, player) {
return player.countCards("hes", { color: "black" }) > 0;
},
- direct: true,
- content() {
- "step 0";
- player
+ async cost(event, trigger, player) {
+ event.result = await player
.chooseCard(get.translation(trigger.player) + "的" + (trigger.judgestr || "") + "判定为" + get.translation(trigger.player.judging[0]) + "," + get.prompt("guidao"), "hes", function (card) {
if (get.color(card) != "black") return false;
- var player = _status.event.player;
- var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player);
+ const player = _status.event.player;
+ const mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player);
if (mod2 != "unchanged") return mod2;
- var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player);
+ const mod = game.checkMod(card, player, "unchanged", "cardRespondable", player);
if (mod != "unchanged") return mod;
return true;
})
.set("ai", function (card) {
- var trigger = _status.event.getTrigger();
- var player = _status.event.player;
- var judging = _status.event.judging;
- var result = trigger.judge(card) - trigger.judge(judging);
- var attitude = get.attitude(player, trigger.player);
+ const trigger = _status.event.getTrigger();
+ const player = _status.event.player;
+ const judging = _status.event.judging;
+ const result = trigger.judge(card) - trigger.judge(judging);
+ const attitude = get.attitude(player, trigger.player);
if (attitude == 0 || result == 0) return 0;
if (attitude > 0) {
return result;
@@ -7366,23 +7245,17 @@ const skills = {
return -result;
}
})
- .set("judging", trigger.player.judging[0]);
- "step 1";
- if (result.bool) {
- player.respond(result.cards, "highlight", "guidao", "noOrdering");
- } else {
- event.finish();
- }
- "step 2";
- if (result.bool) {
- player.$gain2(trigger.player.judging[0]);
- player.gain(trigger.player.judging[0]);
- trigger.player.judging[0] = result.cards[0];
- trigger.orderingCards.addArray(result.cards);
- game.log(trigger.player, "的判定牌改为", result.cards[0]);
- }
- "step 3";
- game.delay(2);
+ .set("judging", trigger.player.judging[0])
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ await player.respond(event.cards, "highlight", "guidao", "noOrdering");
+ player.$gain2(trigger.player.judging[0]);
+ await player.gain(trigger.player.judging[0]);
+ trigger.player.judging[0] = event.cards[0];
+ trigger.orderingCards.addArray(event.cards);
+ game.log(trigger.player, "的判定牌改为", event.cards[0]);
+ await game.asyncDelay(2);
},
ai: {
rejudge: true,
@@ -7402,8 +7275,8 @@ const skills = {
},
chooseButton:{
dialog:function(){
- var list=['sha','tao','jiu','taoyuan','wugu','juedou','huogong','jiedao','tiesuo','guohe','shunshou','wuzhong','wanjian','nanman'];
- for(var i=0;i=3&&player.hp>=3) return 0;
- for(var i=0;i 1) str += "中的一人";
return str;
},
@@ -7505,9 +7378,9 @@ const skills = {
},
//usable:1,
//forceaudio:true,
- content() {
- player.give(cards, target);
- target.addTempSkill("huangtian3", "phaseUseEnd");
+ async content(event, trigger, player) {
+ await player.give(event.cards, event.target);
+ event.target.addTempSkill("huangtian3", "phaseUseEnd");
},
ai: {
expose: 0.3,
@@ -7528,11 +7401,11 @@ const skills = {
filter(event, player) {
if (player.hasSkill("guhuo_phase")) return false;
if (!player.countCards("hs")) return false;
- for (var i of lib.inpile) {
- var type = get.type(i);
+ for (const i of lib.inpile) {
+ const type = get.type(i);
if ((type == "basic" || type == "trick") && event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event)) return true;
if (i == "sha") {
- for (var j of lib.inpile_nature) {
+ for (const j of lib.inpile_nature) {
if (event.filterCard(get.autoViewAs({ name: i, nature: j }, "unsure"), player, event)) return true;
}
}
@@ -7541,29 +7414,29 @@ const skills = {
},
chooseButton: {
dialog(event, player) {
- var list = [];
- for (var i of lib.inpile) {
+ const list = [];
+ for (const i of lib.inpile) {
if (event.type != "phase") if (!event.filterCard(get.autoViewAs({ name: i }, "unsure"), player, event)) continue;
- var type = get.type(i);
+ const type = get.type(i);
if (type == "basic" || type == "trick") list.push([type, "", i]);
if (i == "sha") {
if (event.type != "phase") if (!event.filterCard(get.autoViewAs({ name: i, nature: j }, "unsure"), player, event)) continue;
- for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]);
+ for (const j of lib.inpile_nature) list.push(["基本", "", "sha", j]);
}
}
return ui.create.dialog("蛊惑", [list, "vcard"]);
},
filter(button, player) {
- var evt = _status.event.getParent();
+ const evt = _status.event.getParent();
return evt.filterCard({ name: button.link[2], nature: button.link[3] }, player, evt);
},
check(button) {
- var player = _status.event.player;
- var enemyNum = game.countPlayer(function (current) {
+ const player = _status.event.player;
+ const enemyNum = game.countPlayer(function (current) {
return current != player && !current.hasSkill("chanyuan") && (get.realAttitude || get.attitude)(current, player) < 0;
});
- var card = { name: button.link[2], nature: button.link[3] };
- var val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1;
+ const card = { name: button.link[2], nature: button.link[3] };
+ const val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1;
if (val <= 0) return 0;
if (enemyNum) {
if (
@@ -7586,12 +7459,12 @@ const skills = {
backup(links, player) {
return {
filterCard(card, player, target) {
- var result = true;
- var suit = card.suit,
+ let result = true;
+ const suit = card.suit,
number = card.number;
card.suit = "none";
card.number = null;
- var mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player);
+ const mod = game.checkMod(card, player, "unchanged", "cardEnabled2", player);
if (mod != "unchanged") result = mod;
card.suit = suit;
card.number = number;
@@ -7608,21 +7481,21 @@ const skills = {
number: null,
},
ai1(card) {
- var player = _status.event.player;
- var enemyNum = game.countPlayer(function (current) {
+ const player = _status.event.player;
+ const enemyNum = game.countPlayer(function (current) {
return current != player && !current.hasSkill("chanyuan") && (get.realAttitude || get.attitude)(current, player) < 0;
});
- var cardx = lib.skill.xinfu_guhuo_backup.viewAs;
+ const cardx = lib.skill.xinfu_guhuo_backup.viewAs;
if (enemyNum) {
if (card.name == cardx.name && (card.name != "sha" || get.is.sameNature(card, cardx))) return 2 + Math.random() * 3;
else if (lib.skill.xinfu_guhuo_backup.aiUse < 0.5 && !player.isDying()) return 0;
}
return 6 - get.value(card);
},
- precontent() {
+ async precontent(event, trigger, player) {
player.logSkill("xinfu_guhuo");
player.addTempSkill("guhuo_guess");
- var card = event.result.cards[0];
+ const [card] = event.result.cards;
event.result.card.suit = get.suit(card);
event.result.card.number = get.number(card);
},
@@ -7658,15 +7531,16 @@ const skills = {
filter(event, player) {
return event.skill && (event.skill.indexOf("guhuo_") == 0 || event.skill.indexOf("xinfu_guhuo_") == 0);
},
- content() {
- "step 0";
+ async content(event, trigger, player) {
player.addTempSkill("guhuo_phase");
event.fake = false;
event.betrayer = null;
- var card = trigger.cards[0];
+ const [card] = trigger.cards;
if (card.name != trigger.card.name || (card.name == "sha" && !get.is.sameNature(trigger.card, card))) event.fake = true;
player.popup(trigger.card.name, "metal");
- player.lose(card, ui.ordering).relatedEvent = trigger;
+ const next = player.lose(card, ui.ordering);
+ next.relatedEvent = trigger;
+ await next;
// player.line(trigger.targets,trigger.card.nature);
trigger.throw = false;
trigger.skill = "xinfu_guhuo_backup";
@@ -7677,7 +7551,6 @@ const skills = {
return current != player && !current.hasSkill("chanyuan");
})
.sortBySeat(_status.currentPhase);
-
game.broadcastAll(
function (card, player) {
_status.guhuoNode = card.copy("thrown");
@@ -7701,7 +7574,7 @@ const skills = {
setTimeout(function () {
_status.guhuoNode.style.transition = "all ease-in 0.3s";
_status.guhuoNode.style.transform = "perspective(600px) rotateY(270deg)";
- var onEnd = function () {
+ const onEnd = function () {
_status.guhuoNode.classList.remove("infohidden");
_status.guhuoNode.style.transition = "all 0s";
ui.refresh(_status.guhuoNode);
@@ -7715,53 +7588,50 @@ const skills = {
_status.guhuoNode.listenTransition(onEnd);
}, 300);
};
- if (!event.targets.length) event.goto(3);
- "step 1";
- event.target = event.targets.shift();
- event.target.chooseButton([event.prompt, [["reguhuo_ally", "reguhuo_betray"], "vcard"]], true).set("ai", function (button) {
- var player = _status.event.player;
- var evt = _status.event.getParent("guhuo_guess"),
- evtx = evt.getTrigger();
- if (!evt) return Math.random();
- var card = { name: evtx.card.name, nature: evtx.card.nature, isCard: true };
- var ally = button.link[2] == "reguhuo_ally";
- if (ally && (player.hp <= 1 || get.attitude(player, evt.player) >= 0)) return 1.1;
- if (!ally && get.attitude(player, evt.player) < 0 && evtx.name == "useCard") {
- var eff = 0;
- var targetsx = evtx.targets || [];
- for (var target of targetsx) {
- var isMe = target == evt.player;
- eff += get.effect(target, card, evt.player, player) / (isMe ? 1.5 : 1);
- }
- eff /= 1.5 * targetsx.length || 1;
- if (eff > 0) return 0;
- if (eff < -7) return Math.random() + Math.pow(-(eff + 7) / 8, 2);
- return Math.pow((get.value(card, evt.player, "raw") - 4) / (eff == 0 ? 5 : 10), 2);
+ for (const target of event.targets) {
+ const links = await target
+ .chooseButton([event.prompt, [["reguhuo_ally", "reguhuo_betray"], "vcard"]], true)
+ .set("ai", function (button) {
+ const player = _status.event.player;
+ const evt = _status.event.getParent("guhuo_guess"),
+ evtx = evt.getTrigger();
+ if (!evt) return Math.random();
+ const card = { name: evtx.card.name, nature: evtx.card.nature, isCard: true };
+ const ally = button.link[2] == "reguhuo_ally";
+ if (ally && (player.hp <= 1 || get.attitude(player, evt.player) >= 0)) return 1.1;
+ if (!ally && get.attitude(player, evt.player) < 0 && evtx.name == "useCard") {
+ let eff = 0;
+ const targetsx = evtx.targets || [];
+ for (const target of targetsx) {
+ const isMe = target == evt.player;
+ eff += get.effect(target, card, evt.player, player) / (isMe ? 1.5 : 1);
+ }
+ eff /= 1.5 * targetsx.length || 1;
+ if (eff > 0) return 0;
+ if (eff < -7) return Math.random() + Math.pow(-(eff + 7) / 8, 2);
+ return Math.pow((get.value(card, evt.player, "raw") - 4) / (eff == 0 ? 5 : 10), 2);
+ }
+ return Math.random();
+ })
+ .forResultLinks();
+ if (links[0][2] == "reguhuo_betray") {
+ target.addExpose(0.2);
+ game.log(target, "#y质疑");
+ target.popup("质疑!", "fire");
+ event.betrayer = target;
+ break;
+ } else {
+ game.log(target, "#g不质疑");
+ target.popup("不质疑", "wood");
}
- return Math.random();
- });
- "step 2";
- if (result.links[0][2] == "reguhuo_betray") {
- target.addExpose(0.2);
- game.log(target, "#y质疑");
- target.popup("质疑!", "fire");
- event.betrayer = target;
- } else {
- game.log(target, "#g不质疑");
- target.popup("不质疑", "wood");
- if (targets.length) event.goto(1);
}
- "step 3";
- game.delayx();
+ await game.asyncDelayx();
game.broadcastAll(function (onEnd) {
_status.event.onEnd01 = onEnd;
if (_status.guhuoNode) _status.guhuoNode.listenTransition(onEnd, 300);
}, event.onEnd01);
- "step 4";
- game.delay(2);
- "step 5";
- if (!event.betrayer) event.finish();
- "step 6";
+ await game.asyncDelay(2);
+ if (!event.betrayer) return;
if (event.fake) {
event.betrayer.popup("质疑正确", "wood");
game.log(player, "声明的", trigger.card, "作废了");
@@ -7770,12 +7640,10 @@ const skills = {
trigger.line = false;
} else {
event.betrayer.popup("质疑错误", "fire");
- event.betrayer.addSkills("chanyuan");
+ await event.betrayer.addSkills("chanyuan");
}
- "step 7";
- game.delay(2);
- "step 8";
- if (event.fake) game.broadcastAll(ui.clear);
+ await game.asyncDelay(2);
+ if (event.fake) game.broadcastAll(() => ui.clear()); // game.broadcastAll(ui.clear); 原来的代码抽象喵
},
},
chanyuan: {
@@ -7792,8 +7660,8 @@ const skills = {
mark: true,
intro: {
content(storage, player, skill) {
- var str = "锁定技。你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值为1时,你的其他技能失效。";
- var list = player.getSkills(null, false, false).filter(function (i) {
+ let str = "锁定技。你不能于〖蛊惑〗的结算流程中进行质疑。当你的体力值为1时,你的其他技能失效。";
+ const list = player.getSkills(null, false, false).filter(function (i) {
return lib.skill.rechanyuan.skillBlocker(i, player);
});
if (list.length) str += "
失效技能:" + get.translation(list);
@@ -7806,7 +7674,7 @@ const skills = {
return player.hp == 1;
},
forced: true,
- content() {},
+ async content() {},
},
guhuo_phase: {},
};
diff --git a/character/shenhua/voices.js b/character/shenhua/voices.js
index cc2e37693..e9a9c0710 100644
--- a/character/shenhua/voices.js
+++ b/character/shenhua/voices.js
@@ -4,6 +4,7 @@ export default {
"#re_huangzhong:die": "真哉,老将无用矣……",
"#gzbuqu1": "还不够!",
"#gzbuqu2": "我绝不会倒下!",
+ "#old_zhoutai:die": "已经,尽力了……",
"#jushou1": "我先休息一会!",
"#jushou2": "尽管来吧!",
"#duanliang1_re_xuhuang1": "粮不三载,敌军已犯行军大忌。",
@@ -35,7 +36,7 @@ export default {
"#sp_zhangjiao:die": "黄天既覆……苍生何存?",
"#guhuo_guess1": "道法玄机,变幻莫测。",
"#guhuo_guess2": "如真似幻,扑朔迷离。",
- "#re_yuji:die": "幻化之物,终是算不得真呐……",
+ "#re_yuji:die": "道法玄机,竟被参破……",
"#bazhen1": "你可识得此阵?",
"#bazhen2": "太极生两仪,两仪生四象,四象生八卦。",
"#huoji1": "此火可助我军大获全胜。",
@@ -86,19 +87,19 @@ export default {
"#haoshi2": "拿去拿去,莫跟哥哥客气!",
"#dimeng1": "合纵连横,方能以弱胜强。",
"#dimeng2": "以和为贵,以和为贵。",
- "#re_lusu:die": "一生为国,纵死无憾……",
+ "#re_lusu:die": "此联盟已破,吴蜀休矣……",
"#yinghun1": "不诛此贼三族,则吾死不瞑目!",
"#yinghun2": "以吾魂魄,保佑吾儿之基业。",
"#sunjian:die": "有埋伏!呃……啊!!",
- "#jiuchi1": "呃……再来……一壶……",
- "#jiuchi2": "好酒!好酒!",
- "#roulin1": "美人儿,来,香一个~~",
- "#roulin2": "食色,性也~~",
- "#benghuai1": "呃……",
- "#benghuai2": "我是不是该减肥了?",
- "#baonue21": "杀得好,大大有赏!",
- "#baonue22": "哈哈哈哈哈哈~不愧是我的好部下!",
- "#dongzhuo:die": "为何人人……皆与我为敌?",
+ "#jiuchi1": "呃呵呵呵呵,好酒好酒!",
+ "#jiuchi2": "呃……再来……一壶……",
+ "#roulin1": "食色,性也~~",
+ "#roulin2": "美人儿,来,香一个~~",
+ "#benghuai1": "嗯呃~",
+ "#benghuai2": "哎,我是不是该减肥了?",
+ "#baonue21": "呵哈哈哈哈哈哈哈哈!",
+ "#baonue22": "顺我者昌,逆我者亡!",
+ "#dongzhuo:die": "汉室衰落,非我一人之罪……",
"#luanwu1": "哭喊吧,哀求吧,挣扎吧,然后,死吧!",
"#luanwu2": "哼哼哼……坐山观虎斗!",
"#wansha1": "神仙难救,神仙难救啊。",
diff --git a/character/shiji/characterReplace.js b/character/shiji/characterReplace.js
index a5aaae82f..7467d7f29 100644
--- a/character/shiji/characterReplace.js
+++ b/character/shiji/characterReplace.js
@@ -21,6 +21,7 @@ const characterReplaces = {
sp_jiangqing: ["sp_jiangqing", "tw_jiangqing", "jiangqing"],
kongrong: ["dc_kongrong", "sp_kongrong", "jsrg_kongrong", "kongrong"],
dc_mifuren: ["dc_mifuren", "sp_mifuren"],
+ sp_jiangwan: ["ol_jiangwan", "sp_jiangwan"],
};
export default characterReplaces;
diff --git a/character/shiji/skill.js b/character/shiji/skill.js
index dfe94fe68..eb9873cdf 100644
--- a/character/shiji/skill.js
+++ b/character/shiji/skill.js
@@ -943,6 +943,7 @@ const skills = {
audio: 2,
enable: "phaseUse",
usable: 1,
+ changeSeat: true,
limited: true,
skillAnimation: true,
animationColor: "orange",
@@ -4001,6 +4002,9 @@ const skills = {
content: function () {
game.cardsGotoSpecial(get.cards(), "toRenku");
},
+ ai: {
+ combo: "spsongshu"
+ },
},
spsongshu: {
audio: 2,
@@ -4042,6 +4046,9 @@ const skills = {
intro: { content: "不能对其他角色使用牌" },
},
},
+ ai: {
+ combo: "gebo"
+ },
},
//张机
jishi: {
@@ -4079,6 +4086,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "binglun"
+ },
},
xinliaoyi: {
audio: "liaoyi",
@@ -4294,6 +4304,7 @@ const skills = {
},
},
ai: {
+ combo: "jishi",
order: 2,
result: {
player: 1,
@@ -5059,6 +5070,67 @@ const skills = {
onremove: true,
intro: { content: "已对$发动过此技能" },
},
+ yuanqing: {
+ audio: 2,
+ trigger: { player: "phaseUseEnd" },
+ forced: true,
+ filter: function (event, player) {
+ return player.hasHistory("useCard", function (evt) {
+ return evt.getParent("phaseUse") == event;
+ });
+ },
+ content: function () {
+ var map = {},
+ cards = [];
+ player.getHistory("useCard", function (evt) {
+ if (evt.getParent("phaseUse") == trigger) {
+ var type = get.type2(evt.card, false);
+ if (!map[type]) map[type] = [];
+ }
+ });
+ for (var i = 0; i < ui.discardPile.childNodes.length; i++) {
+ var card = ui.discardPile.childNodes[i],
+ type = get.type2(card, false);
+ if (map[type]) map[type].push(card);
+ }
+ for (var i in map) {
+ if (map[i].length) cards.push(map[i].randomGet());
+ }
+ if (cards.length) {
+ player.$gain2(cards, false);
+ game.cardsGotoSpecial(cards, "toRenku");
+ game.log(player, "将", cards, "置入了仁库");
+ game.delayx();
+ }
+ },
+ init: function (player) {
+ player.storage.renku = true;
+ },
+ ai: {
+ combo: "shuchen"
+ },
+ },
+ shuchen: {
+ audio: 2,
+ init: function (player) {
+ player.storage.renku = true;
+ },
+ trigger: { global: "dying" },
+ forced: true,
+ filter: function (event, player) {
+ return _status.renku.length > 3;
+ },
+ logTarget: "player",
+ content: function () {
+ player.gain(_status.renku, "gain2", "fromRenku");
+ _status.renku.length = 0;
+ game.updateRenku();
+ trigger.player.recover();
+ },
+ ai: {
+ combo: "yuanqing"
+ },
+ },
hxrenshi: {
audio: 2,
enable: "phaseUse",
diff --git a/character/shiji/translate.js b/character/shiji/translate.js
index ae6c651d6..b744e6e43 100644
--- a/character/shiji/translate.js
+++ b/character/shiji/translate.js
@@ -54,7 +54,7 @@ const translates = {
mjchenshi: "陈势",
mjchenshi_player: "陈势",
mjchenshi_target: "陈势",
- mjchenshi_info: "当有角色使用【兵临城下】指定第一个目标后,其可交给你一张牌,并将牌堆的顶三张牌中所有不为【杀】的牌置入弃牌堆;当有角色成为【兵临城下】的目标后,其可交给你一张牌,然后将牌堆顶三张牌中所有的【杀】置入弃牌堆。",
+ mjchenshi_info: "当有角色使用【兵临城下】指定第一个目标后,其可交给你一张牌,并将牌堆顶三张牌中所有不为【杀】的牌置入弃牌堆;当有角色成为【兵临城下】的目标后,其可交给你一张牌,然后将牌堆顶三张牌中所有的【杀】置入弃牌堆。",
mjmouzhi: "谋识",
mjmouzhi_info: "锁定技,当你受到伤害时,若伤害渠道对应的牌和你上次受到的伤害花色相同,则你防止此伤害。",
luotong: "手杀骆统",
@@ -125,8 +125,7 @@ const translates = {
spchijie_info: "每回合限一次。当你成为其他角色使用牌的唯一目标时,你可判定。若结果大于6,则你取消此牌的所有目标。",
reduoji: "夺冀",
reduoji_info: "出牌阶段限一次,你可将一张牌置于其他角色的武将牌上,称为“冀”。当有装备牌因使用而进入一名角色的装备区后,若该角色有“冀”且其为使用者,则你获得此装备牌,其移去一个“冀”并摸一张牌。一名其他角色的回合结束后,若其有“冀”,则你获得其的所有“冀”。",
- wangling: "手杀王淩",
- wangling_prefix: "手杀",
+ wangling: "王淩",
mouli: "谋立",
mouli_info: "出牌阶段限一次,你可以将一张手牌交给一名其他角色,其获得如下效果直到你的下回合开始:其可以将黑色牌当做【杀】,红色牌当做【闪】使用。其第一次触发“使用【杀】/【闪】结算完成后”的时机时,你摸三张牌。",
zifu: "自缚",
@@ -282,7 +281,8 @@ const translates = {
spdifei_info: "锁定技。每回合限一次,当你受到伤害后,你摸一张牌或弃置一张手牌,然后展示所有手牌。若此伤害的渠道为没有花色的牌或你的手牌中没有与此牌花色相同的牌,则你回复1点体力。",
spyanjiao: "严教",
spyanjiao_info: "出牌阶段限一次。你可以将手牌中一种花色的所有牌交给一名其他角色,对其造成1点伤害。然后你于自己的下回合开始时摸等量的牌。",
- sp_jiangwan: "蒋琬",
+ sp_jiangwan: "手杀蒋琬",
+ sp_jiangwan_prefix: "手杀",
spzhenting: "镇庭",
spzhenting_info: "每回合限一次。当你攻击范围内的角色成为【杀】或延时锦囊的目标时,若你不是此牌的使用者且不是此牌的目标,则你可以将此目标改为自己。然后你选择一项:①弃置使用者的一张手牌。②摸一张牌。",
spjincui: "尽瘁",
diff --git a/character/sp/character.js b/character/sp/character.js
index c59422cd4..e8a0960cb 100644
--- a/character/sp/character.js
+++ b/character/sp/character.js
@@ -1,6 +1,9 @@
const characters = {
+ ol_jiangwan: ["male", "shu", 3, ["olziruo", "olxvfa"]],
+ caimao: ["male", "wei", 4, ["olzuolian", "oljingzhou"]],
+ ol_peixiu: ["male", "jin", 4, ["olmaozhu", "oljinlan"]],
yadan: ["male", "qun", 4, ["olqingya", "oltielun"]],
- sp_sunce: ["male", "qun", 4, ["olliantao"]],
+ sp_sunce: ["male", "qun", 4, ["junkliantao"]],
ol_liupi: ["male", "qun", 4, ["olyicheng"]],
ol_lukai: ["male", "wu", 3, ["olxuanzhu", "oljiane"]],
liupan: ["male", "qun", 4, ["olpijing"]],
@@ -9,7 +12,7 @@ const characters = {
tianchou: ["male", "qun", 4, ["olshandao"]],
liyi: ["male", "wu", 4, ["olchanshuang", "olzhanjin"]],
caoyu: ["male", "wei", 3, ["olgongjie", "olxiangxv", "olxiangzuo"]],
- ol_liwan: ["female", "wei", 3, ["ollianju", "olsilv"]],
+ ol_liwan: ["female", "wei", 3, ["relianju", "resilv"]],
ol_dingshangwan: ["female", "wei", 3, ["olfudao", "olfengyan"]],
zhangyan: ["male", "qun", 4, ["olsuji", "ollangdao"]],
ol_tw_zhangji: ["male", "wei", 3, ["skill_zhangji_A", "skill_zhangji_B"], ["unseen"]],
diff --git a/character/sp/dynamicTranslate.js b/character/sp/dynamicTranslate.js
index 4b0d4db01..f15947b4d 100644
--- a/character/sp/dynamicTranslate.js
+++ b/character/sp/dynamicTranslate.js
@@ -87,5 +87,9 @@ const dynamicTranslates = {
if (player.storage.olxuanzhu) return '转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。';
return '转换技,每回合限一次,你可以将一张牌称为“玄”置于武将牌上,然后视为使用:阴,任意基本牌;阳,任意普通锦囊牌(须指定目标且仅指定一个目标)。若此次置于武将牌上的“玄”:不为装备牌,你弃置一张牌;为装备牌,你将所有“玄”置入弃牌堆,然后摸等量的牌。';
},
+ olziruo(player){
+ if (player.storage.olziruo) return '转换技,锁定技。①你不能整理手牌。②当你使用最{阴:左;阳:右}侧的手牌时,你摸一张牌。';
+ return '转换技,锁定技。①你不能整理手牌。②当你使用最{阴:左;阳:右}侧的手牌时,你摸一张牌。';
+ },
};
export default dynamicTranslates;
diff --git a/character/sp/intro.js b/character/sp/intro.js
index 5aac7efd8..c83a87dc1 100644
--- a/character/sp/intro.js
+++ b/character/sp/intro.js
@@ -1,4 +1,5 @@
const characterIntro = {
+ caimao: "蔡瑁,字德珪,生卒年不详。襄阳蔡州人,东汉末年荆州名士。少年时与曹操交好。初平元年(公元190年),刘表为荆州刺史。时宗贼猖獗,蔡瑁协助刘表诛杀宗贼,平定荆州之地,蔡瑁因此得刘表重用,并在刘表任镇南将军时担任他的军师。刘表病亡后,蔡瑁拥护刘表幼子刘琮继位,并逼迫他投降南征的曹操。蔡瑁在曹操麾下历任从事中郎、司马、长水校尉,受封汉阳亭侯。",
yadan: "雅丹,《三国演义》虚构人物,西羌丞相。诸葛亮伐魏时,魏大都督曹真驰书赴羌,西羌国王彻里吉任命雅丹与元帅越吉起兵15万前去增援,中了诸葛亮之计,被伏兵所困。",
liupan: "刘磐(生卒年不详),山阳高平人,荆州牧刘表从子。与南阳人黄忠共守长沙攸县。为人骁勇,数次为寇于艾、西安诸县。江东孙策于是分海昏、建昌为左右六县,以东莱太史慈为建昌都尉,治海昏,并督诸将共拒刘磐。于是刘磐绝迹不复为寇。",
guotu: "郭图(?-205年),字公则,颍川(治今河南省禹州市)人。东汉末年袁绍帐下谋士。韩馥统冀州时,郭图与荀谌等人奉袁绍之命,说服韩馥让位。袁绍统一河北后,郭图与审配等人力劝袁绍统率大军攻打曹操。袁绍死后,袁尚继位。郭图与辛评为袁谭效力,挑唆袁谭攻击袁尚。建安十年(205年),郭图和袁谭一同被曹操所杀。",
@@ -83,7 +84,6 @@ const characterIntro = {
bianfuren: "武宣皇后卞氏(159年12月30日-230年7月9日),琅邪开阳(今山东临沂)人,魏武帝曹操的正妻(继室),魏文帝曹丕、任城威王曹彰、陈思王曹植、萧怀王曹熊的母亲。原本是倡家,即汉代专门从事音乐歌舞的乐人家庭,后来与曹操成婚,建安初年,原配丁夫人被废,卞夫人成为曹操的正妻。曹丕继位后尊其为皇太后,曹叡继位后尊其为太皇太后。卞后在太和四年去世,与魏武帝曹操合葬高陵。",
shamoke: "沙摩柯(?-222年),东汉末三国时期五溪蛮首领。汉章武元年(221年)初,为报关羽被东吴杀害之仇,刘备亲自领兵攻孙权,以金锦爵赏诱沙摩柯助战。章武二年(222年),吴大都督陆逊以火攻破刘备,率诸军齐击,汉军四十多个营寨被攻破,沙摩柯在大乱中匹马奔逃,被乱军杀死。",
lvfan: "吕范(?-228年),字子衡。汝南郡细阳县(今安徽太和)人。汉末至三国时期吴国重臣。吕范年轻为汝南县吏,后避难寿春,结识孙策。此后随孙策、孙权征伐四方,对稳固孙氏在江东的统治做出了杰出的贡献,孙权将其比之于东汉开国元勋吴汉。吴国建立后,吕范累官至前将军、假节、扬州牧,封南昌侯。黄武七年(228年),吕范被拜为大司马,未得授官,便已病逝。孙权悲痛不已,遣使赠其大司马印绶。孙权还都建业后,以太牢礼祭祀吕范。",
- liqueguosi: "请分别查看「李傕」和「郭汜」的武将介绍。",
maojie: "毛玠(?—216年),字孝先,陈留平丘(今河南封丘)人。东汉末年大臣。年少时为县吏,以清廉公正著称。因战乱而打算到荆州避乱,但中途知道刘表政令不严明,因而改往鲁阳。后来投靠曹操,提出“奉天子以令不臣,脩耕植,畜军资”的战略规划,得到曹操的欣赏。
毛玠与崔琰主持选举,所举用的都是清廉正直之士。而毛玠为人廉洁,激起天下廉洁之风,一改朝中奢华风气。曹操大为赞赏,曹丕也亲自去拜访他。
曹操获封魏公后,毛玠改任尚书仆射,再典选举。又密谏曹操应该立嫡长子曹丕为魏国太子。崔琰被杀后,毛玠十分不快。后来有人诬告毛玠,曹操大怒,将毛玠收于狱中。及后在桓阶、和洽营救下,只被免职,不久逝世于家中。曹操在他死后赐他棺材和钱帛。",
huangfusong: "字义真。安定郡朝那县(今宁夏彭阳)人。于黄巾起义时,以中郎将身份讨伐黄巾,用火攻大破张梁、张宝。后接替董卓进攻张梁,连胜七阵。掘张角墓,拜左车骑将军、冀州牧,因拒绝贿赂宦官而被免职。 董卓死,王允命其与吕布等共至郿坞抄籍董卓家产、人口,皇甫嵩将坞中所藏良家子女,尽行释放。",
diff --git a/character/sp/skill.js b/character/sp/skill.js
index abe7fb48a..da7f27964 100644
--- a/character/sp/skill.js
+++ b/character/sp/skill.js
@@ -2,6 +2,433 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
+ //蒋济
+ olziruo: {
+ audio: 2,
+ trigger: { player: "useCard" },
+ filter(event, player) {
+ if (!event.olziruo || !event.olziruo[player.playerid]) return false;
+ return event.olziruo[player.playerid][Boolean(player.storage.olziruo) ? 1 : 0];
+ },
+ forced: true,
+ async content(event, trigger, player) {
+ player.changeZhuanhuanji("olziruo");
+ await player.draw();
+ },
+ mark: true,
+ marktext: "☯",
+ zhuanhuanji: true,
+ intro: { content: storage => "当你使用最" + (storage ? "右" : "左") + "侧的卡牌时,你摸一张牌" },
+ global: "olziruo_mark",
+ ai: { noSortCard: true },
+ mod: {
+ aiOrder(player, card, num) {
+ if (typeof card == "object") {
+ const cards = player.getCards("h");
+ if (cards.indexOf(card) == (player.storage.olziruo ? cards.length - 1 : 0)) return num + 10;
+ }
+ },
+ },
+ subSkill: {
+ mark: {
+ charlotte: true,
+ trigger: { player: "useCardBegin" },
+ filter(event, player) {
+ const cards = player.getCards("h");
+ if (!cards.length) return false;
+ return (event.cards || []).some(card => cards[0] == card || cards[cards.length - 1] == card);
+ },
+ forced: true,
+ popup: false,
+ content() {
+ const cards = player.getCards("h");
+ if (!trigger.olziruo) trigger.olziruo = {};
+ trigger.olziruo[player.playerid] = [trigger.cards.some(card => cards[0] == card), trigger.cards.some(card => cards[cards.length - 1] == card)];
+ },
+ },
+ },
+ },
+ olxvfa: {
+ audio: 2,
+ enable: "phaseUse",
+ filter(event, player) {
+ return (!player.hasSkill("olxvfa_0") && player.countCards("h")) || (!player.hasSkill("olxvfa_1") && player.getExpansions("olxvfa").length);
+ },
+ chooseButton: {
+ dialog(_, player) {
+ let dialog = ui.create.dialog("蓄发:请选择一项", "hidden");
+ const list = [
+ ["0", "将至少一半手牌称为“蓄发”置于武将牌上,然后可以将一张牌当作“蓄发”牌中的一张普通锦囊牌使用"],
+ ["1", "移去至少一半“蓄发”牌,然后可以将一张牌当作其中一张普通锦囊牌使用"],
+ ].filter(listx => {
+ if (listx[0] == "0") return !player.hasSkill("olxvfa_0") && player.countCards("h");
+ return !player.hasSkill("olxvfa_1") && player.getExpansions("olxvfa").length;
+ });
+ dialog.add([list, "textbutton"]);
+ if (list.length == 1) dialog.direct = true;
+ return dialog;
+ },
+ filter(button, player) {
+ if (button.link == "0") return !player.hasSkill("olxvfa_0") && player.countCards("h");
+ return !player.hasSkill("olxvfa_1") && player.getExpansions("olxvfa").length;
+ },
+ check: () => 1 + Math.random(),
+ backup: links => get.copy(lib.skill["olxvfa_" + ["put", "remove"][parseInt(links[0])]]),
+ prompt(links) {
+ if (links[0] == "0") return "###蓄发###将至少一半手牌称为“蓄发”置于武将牌上,然后可以将一张牌当作“蓄发”牌中的一张普通锦囊牌使用";
+ return "###蓄发###移去一半“蓄发”牌,然后可以将一张牌当作其中一张普通锦囊牌使用";
+ },
+ },
+ intro: {
+ content: "expansion",
+ markcount: "expansion",
+ },
+ onremove(player, skill) {
+ const cards = player.getExpansions(skill);
+ if (cards.length) player.loseToDiscardpile(cards);
+ },
+ subSkill: {
+ backup: {},
+ 0: { charlotte: true },
+ 1: { charlotte: true },
+ put: {
+ audio: "olxvfa",
+ filterCard: true,
+ selectCard: () => [Math.ceil(get.event("player").countCards("h") / 2), Infinity],
+ position: "h",
+ check(card) {
+ const player = get.event("player"),
+ value = player.getUseValue(card, true);
+ if (value > 0) return get.type(card) == "trick" ? 20 + value : 0;
+ return 15 - get.value(card) - get.useful(card);
+ },
+ lose: false,
+ discard: false,
+ delay: 0,
+ async content(event, trigger, player) {
+ player.addTempSkill("olxvfa_0", "phaseUseAfter");
+ await player.addToExpansion(event.cards, player, "give").set("gaintag", ["olxvfa"]);
+ const cards = player.getExpansions("olxvfa");
+ if (cards.some(card => get.type(card) == "trick" && player.hasCard(cardx => player.hasUseTarget(get.autoViewAs({ name: card.name }, [cardx]), true), "hes"))) {
+ const result = await player
+ .chooseButton(['###蓄发###是否将一张牌当作一张“蓄发”牌使用?
', cards])
+ .set("filterButton", button => {
+ const player = get.event("player"),
+ card = button.link;
+ return get.type(card) == "trick" && player.hasCard(cardx => player.hasUseTarget(get.autoViewAs({ name: card.name }, [cardx]), true), "hes");
+ })
+ .set("ai", button => {
+ const player = get.event("player"),
+ card = button.link;
+ return player.getUseValue({ name: card.name, isCard: true }, true);
+ })
+ .forResult();
+ if (result.bool) {
+ const card = result.links[0];
+ game.broadcastAll(function (card) {
+ lib.skill.olxvfa_backupx.viewAs = { name: card.name };
+ }, card);
+ await player
+ .chooseToUse()
+ .set("openskilldialog", "###蓄发###将一张牌当作【" + get.translation(card.name) + "】使用")
+ .set("norestore", true)
+ .set("addCount", false)
+ .set("_backupevent", "olxvfa_backupx")
+ .set("custom", {
+ add: {},
+ replace: { window: function () {} },
+ })
+ .backup("olxvfa_backupx");
+ }
+ }
+ },
+ },
+ remove: {
+ audio: "olxvfa",
+ filterCard: () => false,
+ selectCard: -1,
+ delay: 0,
+ async content(event, trigger, player) {
+ player.addTempSkill("olxvfa_1", "phaseUseAfter");
+ const cards = player.getExpansions("olxvfa"),
+ num = Math.ceil(cards.length / 2);
+ const result = await player
+ .chooseButton(['###蓄发###请移去至少' + get.cnNumber(num) + '张“蓄发”牌
', cards], [num, Infinity], true)
+ .set("ai", button => {
+ const player = get.event("player"),
+ value = player.getUseValue(button.link, true);
+ if (value > 0 && get.type(button.link) == "trick") {
+ if (
+ !ui.selected.buttons.some(but => {
+ return get.type(but.link) == "trick" && player.getUseValue(but.link, true) > 0;
+ })
+ )
+ return 20 + value;
+ return 0;
+ }
+ return 1 / (get.useful(button.link) || 0.5);
+ })
+ .forResult();
+ if (result.bool) {
+ const cardx = result.links;
+ await player.loseToDiscardpile(cardx);
+ if (cardx.some(card => get.type(card) == "trick" && player.hasCard(cardxx => player.hasUseTarget(get.autoViewAs({ name: card.name }, [cardxx]), true), "hes"))) {
+ const result2 = await player
+ .chooseButton(['###蓄发###是否将一张牌当作一张移去的“蓄发”牌使用?
', cardx])
+ .set("filterButton", button => {
+ const player = get.event("player"),
+ card = button.link;
+ return get.type(card) == "trick" && player.hasCard(cardx => player.hasUseTarget(get.autoViewAs({ name: card.name }, [cardx]), true), "hes");
+ })
+ .set("ai", button => {
+ const player = get.event("player"),
+ card = button.link;
+ return player.getUseValue({ name: card.name, isCard: true }, true);
+ })
+ .forResult();
+ if (result2.bool) {
+ const card = result2.links[0];
+ game.broadcastAll(function (card) {
+ lib.skill.olxvfa_backupx.viewAs = { name: card.name };
+ }, card);
+ await player
+ .chooseToUse()
+ .set("openskilldialog", "###蓄发###将一张牌当作【" + get.translation(card.name) + "】使用")
+ .set("norestore", true)
+ .set("addCount", false)
+ .set("_backupevent", "olxvfa_backupx")
+ .set("custom", {
+ add: {},
+ replace: { window: function () {} },
+ })
+ .backup("olxvfa_backupx");
+ }
+ }
+ }
+ },
+ },
+ backupx: {
+ filterCard: true,
+ position: "hes",
+ check(card) {
+ const player = get.event("player");
+ if (player.hasValueTarget(card, true, true)) return 0;
+ if (player.hasSkill("olziruo")) {
+ const cards = player.getCards("h");
+ if (cards.indexOf(card) == (player.storage.olziruo ? cards.length - 1 : 0)) {
+ return 15 - get.value(card);
+ }
+ }
+ return 5 - get.value(card);
+ },
+ log: false,
+ precontent() {
+ delete event.result.skill;
+ },
+ },
+ },
+ ai: {
+ order: 1,
+ result: { player: 1 },
+ },
+ },
+ //蔡瑁
+ olzuolian: {
+ audio: 2,
+ enable: "phaseUse",
+ filter(event, player) {
+ return player.getHp() > 0 && game.hasPlayer(target => target.countCards("h"));
+ },
+ filterTarget(card, player, target) {
+ return target.countCards("h");
+ },
+ selectTarget() {
+ return [1, get.event("player").getHp()];
+ },
+ usable: 1,
+ multitarget: true,
+ multiline: true,
+ async content(event, trigger, player) {
+ const targets = event.targets.sortBySeat();
+ const cards = targets.slice().map(i => i.getCards("h").randomGet());
+ const videoId = lib.status.videoId++;
+ game.broadcastAll(
+ (targets, cards, id, player) => {
+ let dialog = ui.create.dialog(get.translation(player) + "发动了【佐练】", cards);
+ dialog.videoId = id;
+ const getName = target => {
+ if (target._tempTranslate) return target._tempTranslate;
+ var name = target.name;
+ if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"];
+ return get.translation(name);
+ };
+ for (let i = 0; i < targets.length; i++) {
+ dialog.buttons[i].querySelector(".info").innerHTML = getName(targets[i]);
+ }
+ },
+ targets,
+ cards,
+ videoId,
+ player
+ );
+ await game.asyncDelay(3);
+ game.broadcastAll("closeDialog", videoId);
+ const cards_cardPile = Array.from(ui.cardPile.childNodes).filter(i => i.name == "sha" && get.nature(i, false));
+ const cards_discardPile = Array.from(ui.discardPile.childNodes).filter(i => i.name == "sha" && get.nature(i, false));
+ if (!Boolean(cards_cardPile.length + cards_discardPile.length)) {
+ player.popup("杯具");
+ player.chat("我属性【杀】呢?!");
+ game.log("但牌堆和弃牌堆都没有属性【杀】!");
+ return;
+ }
+ const result = await player
+ .chooseToMove("佐练:选择交换展示牌和牌堆或弃牌堆中的属性【杀】")
+ .set(
+ "list",
+ (function (cards, cardPile, discardPile) {
+ let list = [["展示手牌", cards, "olzuolian_tag"]];
+ if (cardPile.length) {
+ list.push(["牌堆", cardPile]);
+ }
+ if (discardPile.length) {
+ list.push(["弃牌堆", discardPile]);
+ }
+ return list;
+ })(cards, cards_cardPile, cards_discardPile)
+ )
+ .set("filterMove", (from, to, moved) => {
+ if (typeof to == "number") return false;
+ const cards=get.event("cards");
+ if(cards.includes(from.link)==cards.includes(to.link)) return false;
+ for(const pl of [[from.link,to.link],[to.link,from.link]]){
+ if(cards.includes(pl[0])&&moved[0].includes(pl[1])&&cards.indexOf(pl[0])!=moved[0].indexOf(pl[1])) return false;
+ }
+ return true;
+ })
+ .set("processAI", list => {
+ return list.map(i => i[1]);
+ })
+ .set("cards", cards)
+ .forResult();
+ if (result.bool) {
+ const cardsx = result.moved[0];
+ for (let i = 0; i < cardsx.length; i++) {
+ const current = targets[i],
+ card = cardsx[i];
+ if (!cards.includes(card)) {
+ if (cards_cardPile.includes(card)) {
+ current.$throw([cards[i]], 1000);
+ await current
+ .lose([cards[i]], ui.cardPile)
+ .set("insert_index", () => {
+ return ui.cardPile.childNodes[get.event("num")];
+ })
+ .set("num", cards_cardPile.indexOf(card));
+ } else if (cards_discardPile.includes(card)) {
+ await current.loseToDiscardpile(cards[i]);
+ }
+ await current.gain(card, "gain2");
+ }
+ }
+ }
+ },
+ ai: {
+ order: 10,
+ result: {
+ target(player, target) {
+ //插个眼,等PZ157拯救此AI
+ return 0.5 - Math.random();
+ },
+ },
+ },
+ },
+ oljingzhou: {
+ audio: 2,
+ trigger: { player: "damageBegin3" },
+ filter(event, player) {
+ return player.getHp() > 0;
+ },
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(get.prompt2("oljingzhou"), [1, player.getHp()])
+ .set("ai", target => {
+ const player = get.event("player"),
+ trigger = get.event().getTrigger();
+ if (trigger.hasNature() && target == player) {
+ return -get.effect(target, { name: "tiesuo" }, player, player);
+ }
+ return get.effect(target, { name: "tiesuo" }, player, player);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ for (const i of event.targets) {
+ await i.link(!i.isLinked());
+ }
+ },
+ },
+ //裴秀
+ //我们三国杀也有属于自己的爽文.jpg
+ olmaozhu: {
+ audio: 2,
+ trigger: { source: "damageBegin1" },
+ filter(event, player) {
+ const count = lib.skill.olmaozhu.countSkill;
+ if (!player.isPhaseUsing() || count(player) <= count(event.player)) return false;
+ const evtx = event.getParent("phaseUse");
+ return !player.getHistory("sourceDamage", evt => {
+ return evt.getParent("phaseUse") == evtx && count(player) > count(evt.player);
+ }).length;
+ },
+ forced: true,
+ logTarget: "player",
+ content() {
+ trigger.increase("num");
+ },
+ countSkill(player) {
+ //飞扬跋扈,OL你无敌了
+ const list = [
+ ["feiyang", "飞扬"],
+ ["bahu", "跋扈"],
+ ];
+ return player.getSkills(null, false, false).filter(i => {
+ if (list.some(text => i.includes(text[0]) && get.translation(i) == text[1])) return true;
+ const info = get.info(i);
+ return !info || !info.charlotte;
+ }).length;
+ },
+ mod: {
+ cardUsable(card, player, num) {
+ if (card.name == "sha") return num + lib.skill.olmaozhu.countSkill(player);
+ },
+ maxHandcard(player, num) {
+ return num + lib.skill.olmaozhu.countSkill(player);
+ },
+ },
+ },
+ oljinlan: {
+ audio: 2,
+ enable: "phaseUse",
+ filter(event, player) {
+ const count = lib.skill.olmaozhu.countSkill;
+ return player.countCards("h") < Math.max(...game.filterPlayer().map(i => count(i)));
+ },
+ filterCard: () => false,
+ selectCard: [0, 1],
+ prompt() {
+ const count = lib.skill.olmaozhu.countSkill;
+ return "将手牌数摸至" + get.cnNumber(Math.max(...game.filterPlayer().map(i => count(i)))) + "张";
+ },
+ usable: 1,
+ content() {
+ const count = lib.skill.olmaozhu.countSkill;
+ player.drawTo(Math.max(...game.filterPlayer().map(i => count(i))));
+ },
+ ai: {
+ order: 0.000000114514191981,
+ result: { player: 1 },
+ },
+ },
//鸭蛋
olqingya: {
audio: 2,
@@ -254,7 +681,7 @@ const skills = {
},
async cost(event, trigger, player) {
event.result = await player
- .chooseTarget(get.prompt2("olliantao"), lib.filter.notMe)
+ .chooseTarget(get.prompt2(event.name.slice(0, -"_cost".length)), lib.filter.notMe)
.set("ai", target => {
const player = get.event("player"),
att = get.attitude(player, target);
@@ -364,6 +791,7 @@ const skills = {
.reduce((sum, evt) => sum + evt.num, 0);
if (num) await player.draw(num);
if (
+ event.name == "olliantao" &&
!game.hasPlayer2(current => {
return current.getHistory("damage", evt => {
return evt.getParent(4) == event;
@@ -374,6 +802,16 @@ const skills = {
player.addTempSkill("olliantao_buff");
player.addMark("olliantao_buff", 3, false);
}
+ if (
+ event.name == "junkliantao" &&
+ !target.getHistory("damage", evt => {
+ return evt.getParent(4) == event;
+ }).length
+ ) {
+ await player.draw();
+ player.addTempSkill("olliantao_buff");
+ player.addMark("olliantao_buff", 1, false);
+ }
},
subSkill: {
backup: {
@@ -399,6 +837,11 @@ const skills = {
},
},
},
+ //王战孙策,但是通渠
+ junkliantao: {
+ audio: "olliantao",
+ inherit: "olliantao",
+ },
//刘辟
olyicheng: {
audio: 2,
@@ -472,7 +915,7 @@ const skills = {
cards = moved[0].slice();
if (cards.length) {
await game.cardsGotoOrdering(cards);
- for (let i = cards.length - 1; i--; i >= 0) {
+ for (let i = cards.length - 1; i >= 0; i--) {
ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild);
}
game.log(cards, "被放回了牌堆顶");
@@ -496,7 +939,7 @@ const skills = {
cards = hs.slice();
if (cards.length) {
await game.cardsGotoOrdering(cards);
- for (let i = cards.length - 1; i--; i >= 0) {
+ for (let i = cards.length - 1; i >= 0; i--) {
ui.cardPile.insertBefore(cards[i], ui.cardPile.firstChild);
}
game.log(cards, "被放回了牌堆顶");
@@ -1666,6 +2109,9 @@ const skills = {
)
await player.recover(cards.length);
},
+ ai: {
+ combo: "olgongjie"
+ },
},
//OL飞扬
olfeiyang: {
@@ -1843,6 +2289,162 @@ const skills = {
lose: { charlotte: true },
},
},
+ relianju: {
+ audio: "ollianju",
+ trigger: { player: "phaseJieshuBegin" },
+ filter(event, player) {
+ return player.hasHistory("useCard", evt => {
+ return (evt.cards || []).some(card => get.position(card, true) == "d");
+ });
+ },
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(get.prompt("relianju"), "令一名其他角色获得你本回合使用的且进入弃牌堆的至多两张颜色相同的牌", lib.filter.notMe)
+ .set("ai", target => {
+ const player = get.event("player");
+ let att = get.attitude(_status.event.player, target);
+ if (target.hasJudge("lebu")) att /= 2;
+ if (target.hasSkillTag("nogain")) att /= 10;
+ return att / (1 + get.distance(player, target, "absolute"));
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const cards = player
+ .getHistory("useCard", evt => {
+ return (evt.cards || []).some(card => get.position(card, true) == "d");
+ })
+ .reduce((sum, evt) => {
+ return sum.addArray(evt.cards.filter(card => get.position(card, true) == "d"));
+ }, []),
+ target = event.targets[0];
+ const result = await player
+ .chooseButton(["联句:选择令" + get.translation(target) + "获得的牌", cards], [1, 2], true)
+ .set("filterButton", button => {
+ return !ui.selected.buttons.some(but => get.color(but.link) != get.color(button.link));
+ })
+ .set("ai", button => {
+ return get.value(button.link, get.event("target"));
+ })
+ .set("target", target)
+ .forResult();
+ if (result.bool) {
+ const color = get.color(result.links[0], false);
+ await target.gain(result.links, "gain2").set('gaintag', ["resilv"]);
+ player.when({ global: "phaseJieshuBegin" })
+ .filter(
+ evt =>
+ evt.player == target &&
+ target.hasHistory("useCard", evt => {
+ return (evt.cards || []).some(card => get.position(card, true) == "d" && get.color(card) != color);
+ })
+ )
+ .then(() => {
+ const cards = trigger.player
+ .getHistory("useCard", evt => {
+ return (evt.cards || []).some(card => get.position(card, true) == "d" && get.color(card) != color);
+ })
+ .reduce((sum, evt) => {
+ return sum.addArray(evt.cards.filter(card => get.position(card, true) == "d" && get.color(card) != color));
+ }, []);
+ player
+ .chooseButton(["联句:请选择获得的牌", cards], [1, 2], true)
+ .set("filterButton", button => {
+ return !ui.selected.buttons.some(but => get.color(but.link) != get.color(button.link));
+ })
+ .set("ai", button => {
+ return get.value(button.link, get.event("target"));
+ });
+ })
+ .then(() => {
+ if (result.bool) {
+ player.gain(result.links, "gain2").gaintag.add("resilv");
+ }
+ })
+ .vars({ color: color });
+ }
+ },
+ },
+ resilv: {
+ audio: "olsilv",
+ trigger: { player: "damageEnd" },
+ forced: true,
+ content() {
+ player.draw().gaintag = ["resilv"];
+ },
+ group: "resilv_restore",
+ subSkill: {
+ restore: {
+ audio: "olsilv",
+ trigger: { global: ["loseAfter", "loseAsyncAfter"] },
+ filter(event, player) {
+ if (event.type != "discard" || event.getlx === false) return false;
+ if (event.name == "lose") {
+ if (!event.player.isIn()) return false;
+ return event.cards2.some(card => {
+ return (event.gaintag_map[card.cardid] || []).includes("resilv") && get.position(card, true) == "d";
+ });
+ }
+ return game.hasPlayer(target => {
+ return target.hasHistory("lose", evt => {
+ if (evt.getParent() != event || evt.position != ui.discardPile) return false;
+ return evt.cards2.some(card => {
+ if (get.position(card, true) != "d") return false;
+ return (evt.gaintag_map[card.cardid] || []).includes("resilv");
+ });
+ });
+ });
+ },
+ forced: true,
+ logTarget(event, player) {
+ if (event.name == "lose") return event.player;
+ return game
+ .filterPlayer(target => {
+ return target.hasHistory("lose", evt => {
+ if (evt.getParent() != event || evt.position != ui.discardPile) return false;
+ return evt.cards2.some(card => {
+ if (get.position(card, true) != "d") return false;
+ return evt.gaintag_map[card.cardid] && evt.gaintag_map[card.cardid].includes("resilv");
+ });
+ });
+ })
+ .sortBySeat();
+ },
+ async content(event, trigger, player) {
+ if (trigger.name == "lose") {
+ await trigger.player.gain(
+ trigger.cards2.filter(card => {
+ return (trigger.gaintag_map[card.cardid] || []).includes("resilv") && get.position(card, true) == "d";
+ }),
+ "gain2"
+ );
+ } else {
+ for (const target of lib.skill.resilv_restore.logTarget(trigger, player)) {
+ await target.gain(
+ target
+ .getHistory("lose", evt => {
+ if (evt.getParent() != trigger || evt.position != ui.discardPile) return false;
+ return evt.cards2.some(card => {
+ if (get.position(card, true) != "d") return false;
+ return (evt.gaintag_map[card.cardid] || []).includes("resilv");
+ });
+ })
+ .reduce((sum, evt) => {
+ return sum.addArray(
+ evt.cards2.filter(card => {
+ if (get.position(card, true) != "d") return false;
+ return (evt.gaintag_map[card.cardid] || []).includes("resilv");
+ })
+ );
+ }, []),
+ "gain2"
+ );
+ }
+ }
+ },
+ },
+ },
+ },
//丁尚涴
olfudao: {
audio: 2,
@@ -7036,7 +7638,7 @@ const skills = {
},
ai: {
threaten: 0.8,
- halfneg: true,
+ neg: true,
effect: {
player_use(card, player, target) {
if ((!card.isCard || !card.cards) && get.itemtype(card) != "card") return;
@@ -7388,7 +7990,7 @@ const skills = {
}
},
ai: {
- halfneg: true,
+ neg: true,
},
subSkill: {
swap: {
@@ -9337,7 +9939,6 @@ const skills = {
},
ai: {
halfneg: true,
- combo: "fenrui",
threaten: 3.2,
},
},
@@ -20755,49 +21356,46 @@ const skills = {
animationColor: "thunder",
skillAnimation: "legend",
mark: true,
- direct: true,
- content: function () {
- "step 0";
- player
- .chooseTarget(get.prompt2("yongdi"), function (card, player, target) {
- return (target.hasSex("male") || target.name == "key_yuri") && target != player;
- })
- .set("ai", function (target) {
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(
+ get.prompt2("yongdi"),
+ (card, player, target) => {
+ if (player === target) return false;
+ return target.hasSex("male") || target.name == "key_yuri";
+ }
+ )
+ .set("ai", target => {
if (!_status.event.goon) return 0;
- var player = _status.event.player;
- var att = get.attitude(player, target);
+ let player = _status.event.player;
+ let att = get.attitude(player, target);
if (att <= 1) return 0;
- var mode = get.mode();
+ let mode = get.mode();
if (mode == "identity" || (mode == "versus" && (_status.mode == "four" || _status.mode == "guandu"))) {
- if (target.name && lib.character[target.name]) {
- for (var i = 0; i < lib.character[target.name][3].length; i++) {
- if (lib.skill[lib.character[target.name][3][i]].zhuSkill) {
- return att * 2;
- }
- }
- }
+ if (target.getStockSkills(true, true).some(i => {
+ if (target.hasSkill(i)) return false;
+ let info = get.info(i);
+ return info && info.zhuSkill;
+ })) return att * 2;
}
return att;
})
- .set("goon", !player.hasUnknown());
- "step 1";
- if (result.bool) {
- var target = result.targets[0];
- player.logSkill("yongdi", target);
- player.awakenSkill("yongdi");
- target.gainMaxHp();
- target.recover();
- var skills = target.getStockSkills(true, true).filter(skill => {
- if (target.hasSkill(skill)) return false;
- var info = get.info(skill);
- return info && info.zhuSkill;
- });
- if (skills.length) {
- target.addSkills(skills);
- }
- }
+ .set("goon", !player.hasUnknown())
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ player.awakenSkill("yongdi");
+ let target = event.targets[0], mode = get.mode();
+ if (mode !== "identity" || player.identity !== "nei") player.addExpose(0.25);
+ target.gainMaxHp();
+ target.recover();
+ let skills = target.getStockSkills(true, true).filter(skill => {
+ if (target.hasSkill(skill)) return false;
+ let info = get.info(skill);
+ return info && info.zhuSkill;
+ });
+ if (skills.length) target.addSkills(skills);
},
- ai: { expose: 0.2 },
},
regushe: {
audio: "gushe",
@@ -21572,6 +22170,9 @@ const skills = {
},
ai: { threaten: 2 },
},
+ wusheng_guansuo: { audio: 1 },
+ dangxian_guansuo: { audio: 1 },
+ zhiman_guansuo: { audio: 1 },
xiefang: {
mod: {
globalFrom: function (from, to, distance) {
@@ -23902,7 +24503,7 @@ const skills = {
},
kunfen: {
audio: 2,
- audioname: ["ol_sb_jiangwei"],
+ audioname2: { ol_sb_jiangwei: "kunfen_ol_sb_jiangwei" },
trigger: { player: "phaseJieshuBegin" },
locked: function (skill, player) {
if (!player || !player.storage.kunfen) return true;
@@ -24567,6 +25168,9 @@ const skills = {
return event.targets.includes(player) && player != event.player && event.card.name == "sha" && player.hp < player.countCards("h");
},
content: function () {},
+ ai: {
+ neg: true
+ },
unique: true,
gainable: true,
subSkill: {
@@ -24979,7 +25583,12 @@ const skills = {
usable: 1,
content: function () {
"step 0";
- player.judge();
+ player.judge(card => {
+ if (game.hasPlayer(cur => {
+ return get.event("player").canUse("sha", cur);
+ })) return get.number(card);
+ return 1 / get.number(card);
+ });
"step 1";
player.storage.qiangwu = result.number;
player.addTempSkill("qiangwu3", "phaseUseEnd");
@@ -27030,7 +27639,7 @@ const skills = {
juyi: {
skillAnimation: true,
animationColor: "thunder",
- audio: 2,
+ audio: 1,
derivation: ["benghuai", "weizhong"],
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
@@ -27045,8 +27654,9 @@ const skills = {
player.addSkills(["benghuai", "weizhong"]);
},
},
+ benghuai_zhugedan: { audio: 1 },
weizhong: {
- audio: 2,
+ audio: 1,
trigger: { player: ["gainMaxHpEnd", "loseMaxHpEnd"] },
forced: true,
content: function () {
diff --git a/character/sp/sort.js b/character/sp/sort.js
index d9fde9c58..5d9c1a0f1 100644
--- a/character/sp/sort.js
+++ b/character/sp/sort.js
@@ -10,9 +10,9 @@ const characterSort = {
sp_qifu: ["ol_feiyi", "caoying", "panshu", "caochun", "yuantanyuanshang", "caoshuang", "wolongfengchu", "guansuo", "baosanniang", "fengfangnv", "jin_zhouchu"],
sp_wanglang: ["ol_wanglang", "ol_puyuan", "ol_zhouqun"],
sp_zhongdan: ["cuiyan", "huangfusong"],
- sp_guozhan2: ["sp_dongzhuo", "liqueguosi", "zhangren"],
+ sp_guozhan2: ["sp_dongzhuo", "zhangren"],
sp_others: ["hanba", "caiyang"],
- sp_waitforsort: ["ol_luyusheng", "ol_tw_zhangji", "ol_liwan", "ol_liuyan"],
+ sp_waitforsort: ["ol_luyusheng", "ol_tw_zhangji", "ol_liwan", "ol_liuyan", "ol_peixiu", "caimao", "ol_jiangwan"],
};
const characterSortTranslate = {
diff --git a/character/sp/translate.js b/character/sp/translate.js
index e34f4c99a..daabe4292 100644
--- a/character/sp/translate.js
+++ b/character/sp/translate.js
@@ -1189,6 +1189,10 @@ const translates = {
ollianju_info: "结束阶段,你可以令一名其他角色获得你本回合使用的最后一张牌A对应的所有位于弃牌堆的实体牌并记录A的牌名,然后其下个结束阶段可以令你获得其本回合使用的最后一张牌B对应的所有位于弃牌堆的实体牌,然后若A与B的牌名相同,则你失去1点体力;若A与B的牌名不同,则你可以视为使用A。",
olsilv: "思闾",
olsilv_info: "锁定技,每回合每项限一次,当你获得或失去你发动〖联句〗记录的最后一次牌名的同名牌后,你展示这些牌,然后摸一张牌。",
+ relianju: "联句",
+ relianju_info: "结束阶段,你可以令一名其他角色获得你本回合使用的至多两张位于弃牌堆且颜色相同的牌,称为“思闾”,然后你于其下个结束阶段获得其本回合使用的至多两张的位于弃牌堆且颜色相同且颜色不同于你本次获得的牌的颜色的牌,称为“思闾”。",
+ resilv: "思闾",
+ resilv_info: "锁定技。①当你受到伤害后,你摸一张牌,称为“思闾”。②一名角色因弃置“思闾”牌使“思闾”牌进入弃牌堆后,其获得之。",
xueji_old: "血祭",
xueji_old_info: "出牌阶段限一次,你可以弃置一张红色牌并对攻击范围内的至多X名角色各造成1点伤害(X为你已损失的体力值),然后这些角色各摸一张牌。",
oldhuxiao: "虎啸",
@@ -1239,11 +1243,30 @@ const translates = {
sp_sunce_prefix: "SP",
olliantao: "连讨",
olliantao_info: "出牌阶段开始时,你可以令一名其他角色选择一个颜色,然后你依次将此颜色的所有手牌当作【决斗】对其使用直到有一方进入濒死状态,然后你摸X张牌(X为你本次以此法造成的伤害数)。若没有角色因本次技能结算受到伤害,你摸三张牌,本回合手牌上限+3且本回合你不能使用【杀】。",
+ junkliantao: "连讨",
+ junkliantao_info: "出牌阶段开始时,你可以令一名其他角色选择一个颜色,然后你依次将此颜色的所有手牌当作【决斗】对其使用直到有一方进入濒死状态,然后你摸X张牌(X为你本次以此法造成的伤害数)。若其未因本次技能结算受到伤害,你摸一张牌,本回合手牌上限+1且本回合你不能使用【杀】。",
yadan: "雅丹",
olqingya: "倾轧",
olqingya_info: "当你使用【杀】指定唯一目标后,你可从逆时针方向和顺时针方向中选择一个你与其之间角色最少的方向。你弃置该方向下你与其之间的角色各一张手牌,然后你可以于本回合下个阶段结束时使用其中一张牌。",
oltielun: "铁轮",
oltielun_info: "锁定技。你计算与其他角色的距离-X(X为你本轮使用的牌数)。",
+ ol_peixiu: "裴秀",
+ olmaozhu: "茂著",
+ olmaozhu_info: "锁定技。①你的手牌上限和使用【杀】的额定次数+X(X为你拥有的技能数)。②当你于出牌阶段首次对技能数小于你的角色造成伤害时,此伤害+1。",
+ oljinlan: "尽览",
+ oljinlan_info: "出牌阶段限一次,你可以将手牌数摸至Y张(Y为场上技能数最多的角色的技能数)。",
+ oljinlan_append: '补丁×注意事项:
〖飞扬〗〖跋扈〗计入〖茂著〗〖尽览〗的技能数计算',
+ caimao: "蔡瑁",
+ olzuolian: "佐练",
+ olzuolian_tag: "展示牌",
+ olzuolian_info: "出牌阶段限一次,你可以选择至多X名有牌的角色(X为你的体力值),你随机展示这些角色的各一张牌,然后你可以将这些牌与牌堆和弃牌堆中的属性【杀】进行交换。",
+ oljingzhou: "精舟",
+ oljingzhou_info: "当你受到伤害时,你可以选择至多X名角色(X为你的体力值)这些角色中处于/未处于连环状态的角色重置/横置武将牌。",
+ ol_jiangwan:'蒋琬',
+ olziruo:'自若',
+ olziruo_info:'转换技,锁定技。①你不能整理手牌。②当你使用最{阴:左;阳:右}侧的手牌时,你摸一张牌。',
+ olxvfa:'蓄发',
+ olxvfa_info:'出牌阶段各限一次,你可以:①将至少一半手牌称为“蓄发”置于武将牌上,然后你可以将一张牌当作“蓄发”牌中的一张普通锦囊牌使用;②移去至少一半“蓄发”牌,然后你可以将一张牌当作其中一张普通锦囊牌使用。',
};
export default translates;
diff --git a/character/sp/voices.js b/character/sp/voices.js
index 0abc1be1c..d14842631 100644
--- a/character/sp/voices.js
+++ b/character/sp/voices.js
@@ -484,7 +484,8 @@ export default {
"#gongao1": "恪尽职守,忠心事主。",
"#gongao2": "攻城拔寨,建功立业。",
"#juyi1": "司马氏篡权,我当替天伐之!",
- "#juyi2": "司马氏篡权,我当替天伐之!",
+ "#benghuai_zhugedan1": "咳……咳咳……",
+ "#weizhong1": "定当夷司马氏三族!",
"#zhugedan:die": "诸葛一氏定会为我复仇!",
"#kunfen1": "兴蜀需时,众将且勿惫怠!",
"#kunfen2": "纵使困顿难行,亦当砥砺奋进!",
@@ -570,8 +571,6 @@ export default {
"#xingwu1": "哼,不要小瞧女孩子哦!",
"#xingwu2": "姐妹齐心,其利断金。",
"#daxiaoqiao:die": "伯符,公瑾,请一定要守住我们的江东啊!",
- "#zhengnan1": "末将愿承父志,随丞相出征!",
- "#zhengnan2": "索全凭丞相差遣,万死不辞!",
"#luanzhan1": "受袁氏大恩,当效死力。",
"#luanzhan2": "现,正是我乌桓崛起之机。",
"#tadun:die": "呃……不该趟曹袁之争的浑水……",
@@ -654,7 +653,7 @@ export default {
"#chuanxin2": "穿心之痛,细细品吧,哈哈哈哈!",
"#zfengshi1": "大军压境,还不卸甲受降!",
"#zfengshi2": "放下兵器,饶你不死!",
- "#zhangren:die": "老臣,绝不事二主!",
+ "#zhangren:die": "本将军败于诸葛,无憾!",
"#wylianji1": "两计扣用,以催强势。",
"#wylianji2": "容老夫细细思量。",
"#moucheng1": "董贼伏诛,天下太平!",
@@ -722,10 +721,6 @@ export default {
"#shensu1_xiahouba2": "今日有恙在身,须得速战速决!",
"#xiaoji_sp_sunshangxiang1": "弓马何须忌红妆?",
"#xiaoji_sp_sunshangxiang2": "双剑夸巧,不让须眉!",
- "#benghuai_zhugedan1": "咳……咳咳……",
- "#benghuai_zhugedan2": "粮草还可支持几日?",
- "#weizhong1": "定当夷司马氏三族!",
- "#weizhong2": "定当夷司马氏三族!",
"#tiaoxin_sp_jiangwei1": "今日天公作美,怎能不战而退?",
"#tiaoxin_sp_jiangwei2": "贼将无胆,何不早降!",
"#ranshang21": "战火燃尽英雄胆!",
@@ -738,12 +733,12 @@ export default {
"#tianxiang_daxiaoqiao2": "替我挡着吧~",
"#liuli_daxiaoqiao1": "不懂得怜香惜玉么~",
"#liuli_daxiaoqiao2": "交给你了。",
+ "#zhengnan1": "末将愿承父志,随丞相出征!",
+ "#zhengnan2": "索全凭丞相差遣,万死不辞!",
"#wusheng_guansuo1": "逆贼,可识得关氏之勇?",
- "#wusheng_guansuo2": "逆贼,可识得关氏之勇?",
"#dangxian_guansuo1": "各位将军,且让小辈先行出战!",
- "#dangxian_guansuo2": "各位将军,且让小辈先行出战!",
"#zhiman_guansuo1": "蛮夷可抚,不可剿!",
- "#zhiman_guansuo2": "蛮夷可抚,不可剿!",
+ "#guansuo:die": "只恨天下未平,空留遗志……",
"#duanbing_heqi1": "可真是把好刀啊!",
"#reyingzi_heqi1": "人靠衣装马靠鞍!",
"#fenwei_heqi1": "我的船队,要让全建业城都看见!",
@@ -765,4 +760,7 @@ export default {
"#olpijing1": "今青锋在手,必破敌军于域外。",
"#olpijing2": "荆楚多锦绣,安能丧于小儿之手!",
"#liupan:die": "今袍泽离散,无以为战……",
+ "#olqingya1": "罡风从虎,威震四方!",
+ "#olqingya1": "铁车过处,寸草不生!",
+ "#yadan:die": "多谢丞相不杀之恩……",
};
diff --git a/character/sp2/character.js b/character/sp2/character.js
index 945ce3578..1c1b51b05 100644
--- a/character/sp2/character.js
+++ b/character/sp2/character.js
@@ -1,4 +1,8 @@
const characters = {
+ matie: ["male", "qun", 4, ["dczhuiwang", "dcquxian"]],
+ hansong: ["male", "qun", 3, ["dcyinbi", "dcshuaiyan"]],
+ chezhou: ["male", "wei", 4, ["dcshefu", "dcpigua"]],
+ star_zhangzhao: ["male", "wu", 3, ["starzhongyan", "starjinglun"]],
star_sunjian: ["male", "qun", "4/5", ["starruijun", "stargangyi"]],
liqueguosi: ["male", "qun", 4, ["xiongsuan"]],
star_zhangchunhua: ["female", "wei", 3, ["starliangyan", "starminghui"]],
diff --git a/character/sp2/characterReplace.js b/character/sp2/characterReplace.js
index eacc8c7b1..285059751 100644
--- a/character/sp2/characterReplace.js
+++ b/character/sp2/characterReplace.js
@@ -31,7 +31,7 @@ const characterReplaces = {
jsp_guanyu: ["jsp_guanyu", "dc_jsp_guanyu", "jsrg_guanyu"],
mushun: ["mushun", "sp_mushun"],
wangjun: ["dc_wangjun", "wangjun"],
- zoushi: ["re_zoushi", "jsrg_zoushi"],
+ re_zoushi: ["yue_zoushi", "re_zoushi", "jsrg_zoushi"],
zhangmancheng: ["dc_zhangmancheng", "tw_zhangmancheng"],
};
diff --git a/character/sp2/intro.js b/character/sp2/intro.js
index da1b541bd..92e9b96b4 100644
--- a/character/sp2/intro.js
+++ b/character/sp2/intro.js
@@ -1,4 +1,5 @@
const characterIntro = {
+ liqueguosi: "请分别查看「李傕」和「郭汜」的武将介绍。",
tangji: "唐姬,会稽太守唐瑁女,弘农怀王刘辩的妃子。刘辩死后,唐姬回归故里,因节烈不愿改嫁他人,后被汉献帝下诏封为弘农王妃。",
lijue: "李傕(一说“傕”读音“què”)(?—198年),字稚然。北地郡泥阳县(今陕西省耀县)人,汉末群雄之一。东汉末年汉献帝时的军阀、权臣,官至大司马、车骑将军、开府、领司隶校尉、假节。
李傕本为董卓部将,后被董卓的女婿牛辅派遣至中牟与朱儁交战,大破朱儁,进而至陈留、颍川等地劫掠。初平三年(192年)董卓和牛辅被杀后,李傕归无所依,于是采用贾诩之谋,伙同郭汜、张济、樊稠等原董卓部曲将攻向长安。击败吕布,杀死王允等人,占领长安,把持朝廷大权。后诸将不和,李傕在会议上杀死了樊稠,又与郭汜分别劫持了汉献帝和众臣,相互交战,张济率兵赶来和解,于是二人罢兵,李傕出屯池阳黄白城,郭汜、张济等人随汉献帝东归前往弘农。
后来,李傕、郭汜、张济反悔,联合起来追击汉献帝,与杨奉、董承等人几番交战。汉献帝一路逃亡,狼狈不堪,到达安邑,与李傕等人讲和。不久,汉献帝被曹操迎往许都。建安三年(198年),曹操派谒者仆射裴茂召集关西诸将段煨等人征讨李傕,灭其三族。",
zhangji: "张济(?-196年),武威郡祖厉县(今甘肃靖远东南)人。东汉末年割据军阀之一。 张济原为董卓部将,董卓被诛杀后,张济与李傕一同率军攻破长安,任中郎将。不久,升任镇东将军,封平阳侯,出屯弘农。献帝东迁时,张济升任骠骑将军,率军护卫献帝,后来因与董承等人有矛盾,便与李傕、郭汜一同追赶献帝。 建安元年(196年),张济因军队缺粮而进攻穰城,中流矢而死。死后,部队由侄儿张绣接管。",
@@ -64,6 +65,9 @@ const characterIntro = {
mushun: "穆顺,小说《三国演义》中的人物,男,东汉末宦官。献帝欲修书与国舅伏完,共谋图曹公。因顺为宦官中之忠义可托者,乃命顺往送书。顺藏书于发中,潜出禁宫,径至完宅,将书呈上。及完回书付顺,顺乃藏于头髻内,辞完回宫。然公闻信,先于宫门等候,顺回遇公,公喝左右,遍搜身上,并无夹带,放行。忽然风吹落其帽。公又唤回,取帽视之,遍观无物,还帽令戴。顺双手倒戴其帽。公心疑,令左右搜其头发中,搜出伏完书来。公见书大怒,执下顺于密室问之,顺不肯招。当晚将顺、完等宗族二百余口,皆斩于市。",
jsp_guanyu: "关羽,字云长。曾水淹七军、擒于禁、斩庞德、威震华夏,吓得曹操差点迁都躲避,但是东吴偷袭荆州,关羽兵败被害。后传说吕蒙因关羽之魂索命而死。",
liuling: "刘伶(约221年-约300年),字伯伦,西晋沛国(治今安徽濉溪县西北)人,竹林七贤之一,中国魏晋时期作家,名士。
刘伶自幼便失去了父爱,因其父亲身材矮小,及至长大成人后,刘伶身高也不过六尺。魏齐王曹芳正始之末(249年),刘伶已成为当世名重一时的名士,并且常与嵇康、阮籍、阮咸集会于山阳竹林之下,饮酒赋诗,弹琴作歌。晋武帝司马炎泰始初年(265年)前后,曾做过一段时间的建威参军,不久朝廷下诏,入宫中策问。他大谈老庄,强调无为而治,非但没有得到重用,反而连参军之职也被罢免了,从此再无仕进。晋惠帝司马衷永康元年(300年)前后,以寿而终。
刘伶有“品酒第一人”的美称,也被酒行业传颂至今,后人以古瀑河边上的井水酿酒,还取刘伶墓地的黄土垒成窖池酿酒,为了纪念刘伶,当地百姓也将“润泉涌”更名为“刘伶醉”。其传世作品仅有《酒德颂》《北芒客舍》两篇,其中《酒德颂》所表现出的藐视一切存在的气概,敌视礼教之士的反抗精神,既高扬了人格的力量,批判了当时的黑暗政治,同时也抒发了压抑的愤世之情,充满了浪漫色彩,气魄豪迈,用辞又骈偶间行,有无意追求而自至的特点,对后代影响极大。",
+ chezhou: "车胄(?-199年至200年),东汉末年武将,为曹操所置徐州刺史。建安四年,左将军刘备率军出征,前往下邳,于同年或次年杀死车胄。",
+ hansong: "韩嵩(生卒年不详),字德高,南阳人。少好学,贫不改操。不应三公辟命,与同好数人隐居郦西山中。后担任刘表手下的别驾,转为从事中郎。出使许都,被拜为侍中,迁零陵太守。建安十三年(208年),韩嵩与蒯越、傅巽劝刘琮降曹。曹操平定荆州后,拜韩嵩为大鸿胪。",
+ matie: "马铁(?-212年),扶风茂陵(今陕西兴平)人。马腾之子,马超之弟。马腾遭韩遂进攻,乃携马铁等入京受职。马铁被封为骑都尉。后在邺城居住。因其兄马超反曹而被曹操夷灭。",
};
export default characterIntro;
diff --git a/character/sp2/skill.js b/character/sp2/skill.js
index 2ae959823..f5c5b4ccc 100644
--- a/character/sp2/skill.js
+++ b/character/sp2/skill.js
@@ -2,6 +2,361 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
+ //马铁
+ dczhuiwang: {
+ mod: {
+ globalFrom(from, to) {
+ if (from.hp >= to.hp) return -Infinity;
+ },
+ },
+ },
+ dcquxian: {
+ audio: 2,
+ trigger: {
+ player: "phaseUseBegin",
+ },
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(get.prompt("dcquxian"), "选择一名角色,攻击范围内包含其的角色可以对其使用【杀】")
+ .set("ai", target => {
+ const player = get.player();
+ return -get.attitude(player, target);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const target = event.targets[0],
+ targets = game.filterPlayer(current => current.inRange(target)).sortBySeat();
+ if (!targets.length) return;
+ const sha = [],
+ nosha = [];
+ while (targets.length) {
+ const current = targets.shift();
+ const bool = await current
+ .chooseToUse(function (card, player, event) {
+ if (get.name(card) != "sha") return false;
+ return lib.filter.filterCard.apply(this, arguments);
+ }, "驱险:是否对" + get.translation(target) + "使用一张杀?")
+ .set("targetRequired", true)
+ .set("complexSelect", true)
+ .set("filterTarget", function (card, player, target) {
+ if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
+ return lib.filter.targetEnabled.apply(this, arguments);
+ })
+ .set("sourcex", target)
+ .set("addCount", false)
+ .forResultBool();
+ if (bool) sha.push(current);
+ else nosha.push(current);
+ }
+ if (!target.hasHistory("damage", evt => evt.getParent().type == "card" && evt.getParent(4) == event) && sha.length && nosha.length) {
+ for (const i of nosha) await i.loseHp(sha.length);
+ }
+ },
+ },
+ //韩嵩
+ dcyinbi: {
+ mod: {
+ targetInRange(card, player) {
+ if (!game.hasPlayer(current => current != player && current.countCards("h") == player.countCards("h"))) return true;
+ },
+ cardUsable(card, player) {
+ if (!game.hasPlayer(current => current != player && current.countCards("h") == player.countCards("h"))) return Infinity;
+ },
+ maxHandcardBase(player) {
+ if (_status.dcyinbi) return;
+ _status.dcyinbi = true;
+ const num = Math.max(...game.filterPlayer().map(target => target.getHandcardLimit()));
+ delete _status.dcyinbi;
+ return num;
+ },
+ },
+ },
+ dcshuaiyan: {
+ audio: 2,
+ trigger: {
+ global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
+ },
+ filter(event, player, name, target) {
+ return target && target.countCards("h") == player.countCards("h");
+ },
+ getIndex(event, player) {
+ return game
+ .filterPlayer(target => {
+ if (target == player) return false;
+ if (event.getg && event.getg(target) && event.getg(target).length && target.countCards("h") == player.countCards("h")) return true;
+ const evt = event.getl(target);
+ if (evt && evt.hs && evt.hs.length && target.countCards("h") == player.countCards("h")) return true;
+ return false;
+ })
+ .sortBySeat();
+ },
+ logTarget(event, player, triggername, target) {
+ return target;
+ },
+ forced: true,
+ async content(event, trigger, player) {
+ const target = event.targets[0],
+ goon = target.countDiscardableCards(player, "he");
+ let result;
+ if (goon)
+ result = await player
+ .chooseControl()
+ .set("choiceList", ["弃置" + get.translation(target) + "的一张牌", "摸一张牌"])
+ .set("ai", () => {
+ const player = get.player();
+ const eff1 = get.effect(get.event("target"), { name: "guohe_copy2" }, player, player);
+ const eff2 = get.effect(player, { name: "draw" }, player, player);
+ return eff1 > eff2 ? 0 : 1;
+ })
+ .set("target", target)
+ .forResult();
+ else result = { index: 1 };
+ if (result.index == 0) player.discardPlayerCard(target, "he", true);
+ else player.draw();
+ },
+ },
+ //侧肘
+ dcshefu: {
+ audio: 2,
+ trigger: {
+ player: "damageBegin2",
+ source: "damageBegin1",
+ },
+ filter(event, player) {
+ if (!event.source || event.source == event.player) return false;
+ const evt = event.getParent(2);
+ return evt && evt.name == "useCard";
+ },
+ forced: true,
+ logTarget(event, player) {
+ return event.source == player ? event.player : event.source;
+ },
+ content() {
+ const evt = trigger.getParent(2);
+ const cards = evt.cards.filter(card => {
+ if (trigger.source._start_cards.includes(card)) return true;
+ return trigger.source.getAllHistory("gain", evt => {
+ return evt.cards.includes(card);
+ }).length;
+ });
+ trigger.num =
+ cards.length +
+ cards.reduce((sum, card) => {
+ let num = 0,
+ history = trigger.source.actionHistory;
+ for (let i = history.length - 1; i >= 0; i--) {
+ if (history[i].gain.some(evtx => evtx.cards.includes(card))) break;
+ if (history[i].isRound) num++;
+ if (i == 0 && trigger.source._start_cards.includes(card)) num--;
+ }
+ return sum + num;
+ }, 0);
+ },
+ ai: {
+ effect: {
+ target(card, player, target) {
+ if (target == player || !get.tag(card, "damage")) return;
+ if (!(card.cards || []).length) return "zeroplayertarget";
+ },
+ player: function () {
+ return lib.skill.dcshefu.ai.effect.target.apply(this, arguments);
+ },
+ },
+ },
+ },
+ dcpigua: {
+ audio: 2,
+ trigger: { source: "damageSource" },
+ filter(event, player) {
+ if (event.player == player) return false;
+ return event.num > 1 && event.player.isIn() && event.player.countCards("he") && game.roundNumber > 0;
+ },
+ async cost(event, trigger, player) {
+ const target = trigger.player;
+ let result = await player.gainPlayerCard(target, "he", [1, game.roundNumber]).set("prompt", get.prompt2("dcpigua", target)).set("logSkill", ["dcpigua", target]).forResult();
+ result.bool = Boolean((result.cards || []).length);
+ event.result = result;
+ },
+ popup: false,
+ async content(event, trigger, player) {
+ player.addTempSkill("dcpigua_effect");
+ player.addGaintag(event.cards, "dcpigua_effect");
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ onremove(player, skill) {
+ player.removeGaintag(skill);
+ },
+ mod: {
+ ignoredHandcard(card) {
+ if (card.hasGaintag("dcpigua_effect")) return true;
+ },
+ cardDiscardable(card, _, name) {
+ if (name == "phaseDiscard" && card.hasGaintag("dcpigua_effect")) return false;
+ },
+ },
+ },
+ },
+ },
+ //星张昭
+ starzhongyan: {
+ audio: 2,
+ enable: "phaseUse",
+ usable: 1,
+ filter(event, player) {
+ return game.hasPlayer(current => get.info("starzhongyan").filterTarget(null, player, current));
+ },
+ filterTarget(card, player, target) {
+ return target.countCards("h");
+ },
+ async content(event, trigger, player) {
+ const target = event.targets[0],
+ topCards = get.cards(3);
+ await game.cardsGotoOrdering(topCards);
+ await player.showCards(topCards, get.translation(player) + "发动了【忠言】");
+ if (!target.countCards("h")) return;
+ const result = await target
+ .chooseToMove("忠言:交换其中一张牌")
+ .set("list", [
+ ["牌堆顶", topCards],
+ ["你的手牌", target.getCards("h")],
+ ])
+ .set("filterMove", (from, to, moved) => {
+ if (typeof to == "number") return false;
+ var player = _status.event.player;
+ var hs = player.getCards("h");
+ var changed = hs.filter(function (card) {
+ return !moved[1].includes(card);
+ });
+ var changed2 = moved[1].filter(function (card) {
+ return !hs.includes(card);
+ });
+ if (changed.length < 1) return true;
+ var pos1 = moved[0].includes(from.link) ? 0 : 1,
+ pos2 = moved[0].includes(to.link) ? 0 : 1;
+ if (pos1 == pos2) return true;
+ if (pos1 == 0) {
+ if (changed.includes(from.link)) return true;
+ return changed2.includes(to.link);
+ }
+ if (changed2.includes(from.link)) return true;
+ return changed.includes(to.link);
+ })
+ .set("filterOk", moved => {
+ return moved[0].filter(card => get.owner(card)).length == 1;
+ })
+ .set("processAI", function (list) {
+ var cards1 = list[0][1].slice(),
+ cards2 = list[1][1].slice();
+ var card1 = cards1.sort((a, b) => get.value(b) - get.value(a))[0];
+ var card2 = cards2.sort((a, b) => get.value(a) - get.value(b))[0];
+ if (card1 && card2 && get.value(card1) > get.value(card2)) {
+ cards1.remove(card1);
+ cards2.remove(card2);
+ cards1.push(card2);
+ cards2.push(card1);
+ }
+ return [cards1, cards2];
+ })
+ .forResult();
+ if (result.bool) {
+ const lose = result.moved[0].slice();
+ const gain = result.moved[1].slice().filter(i => !get.owner(i));
+ if (lose.some(i => get.owner(i)))
+ await target.lose(
+ lose.filter(i => get.owner(i)),
+ ui.special
+ );
+ for (let i = lose.length - 1; i--; i >= 0) {
+ ui.cardPile.insertBefore(lose[i], ui.cardPile.firstChild);
+ }
+ game.updateRoundNumber();
+ if (gain.length) await target.gain(gain, "draw");
+ if (lose.map(card => get.color(card)).toUniqued().length == 1) {
+ const chosen = [],
+ list = player != target ? [target, player] : [target];
+ for (const current of list) {
+ const goon = game.hasPlayer(i => i.countGainableCards(current, "ej"));
+ const choices = [];
+ const choiceList = ["回复1点体力", "获得场上一张牌"];
+ if (current.isDamaged() && !chosen.includes("选项一")) choices.push("选项一");
+ else choiceList[0] = '' + choiceList[0] + "";
+ if (goon && !chosen.includes("选项二")) choices.push("选项二");
+ else choiceList[1] = '' + choiceList[1] + "";
+ if (!choices.length) continue;
+ const control =
+ choices.length == 1
+ ? choices[0]
+ : await current
+ .chooseControl(choices)
+ .set("choiceList", choiceList)
+ .set("prompt", "忠言:请选择一项")
+ .set("ai", () => {
+ const player = get.player();
+ const eff2 = get.recoverEffect(player, player, player);
+ return eff2 ? 0 : 1;
+ })
+ .forResultControl();
+ chosen.push(control);
+ if (control == "选项一") {
+ await current.recover();
+ } else {
+ const targets = await current
+ .chooseTarget("获得一名角色场上的一张牌", true, (card, player, target) => {
+ const targetx = get.event("targetx");
+ return target.countGainableCards(targetx, "ej") > 0;
+ })
+ .set("ai", target => {
+ const player = get.player();
+ let att = get.attitude(player, target);
+ if (att < 0) att = -Math.sqrt(-att);
+ else att = Math.sqrt(att);
+ return att * lib.card.shunshou.ai.result.target(player, target);
+ })
+ .set("targetx", current)
+ .forResultTargets();
+ await current.gainPlayerCard(targets[0], "ej", true);
+ }
+ }
+ }
+ } else {
+ for (let i = topCards.length - 1; i--; i >= 0) {
+ ui.cardPile.insertBefore(topCards[i], ui.cardPile.firstChild);
+ }
+ game.updateRoundNumber();
+ }
+ },
+ ai: {
+ order: 8,
+ result: {
+ player: 1,
+ target: 1,
+ },
+ },
+ },
+ starjinglun: {
+ audio: 2,
+ trigger: {
+ global: "damageSource",
+ },
+ filter(event, player) {
+ const target = event.source;
+ return target && target.isIn() && get.distance(player, target) <= 1;
+ },
+ check(event, player) {
+ return get.attitude(player, event.source) > 0;
+ },
+ usable:1,
+ logTarget: "source",
+ async content(event, trigger, player) {
+ const target = trigger.source,
+ num = target.countCards("e");
+ if (num) await target.draw(num);
+ await player.useSkill("starzhongyan", [target]);
+ },
+ },
//星孙坚
starruijun: {
audio: 2,
@@ -1162,7 +1517,7 @@ const skills = {
}
},
ai: {
- combo: "mpjiusong"
+ combo: "mpjiusong",
},
},
mpbishi: {
@@ -2227,9 +2582,11 @@ const skills = {
filter: function (event, player) {
return event.card.name == "sha" && event.getParent().triggeredTargets3.length == event.targets.length;
},
+ /*
check: function (event, player) {
return event.targets.some(target => get.effect(target, event.card, player, player) <= 0);
},
+ */
content: function () {
"step 0";
var num = player.countCards("e") + 1;
@@ -2238,7 +2595,7 @@ const skills = {
"step 1";
var num = Math.min(trigger.targets.length, num);
player
- .chooseTarget("铤险:令此杀对其中至多" + get.cnNumber(num) + "个目标无效", [1, num], true, (card, player, target) => {
+ .chooseTarget("铤险:是否令此杀对其中至多" + get.cnNumber(num) + "个目标无效?", [1, num], (card, player, target) => {
return _status.event.getTrigger().targets.includes(target);
})
.set("ai", target => {
@@ -2250,6 +2607,7 @@ const skills = {
trigger.getParent().excluded.addArray(result.targets);
}
},
+ /*
ai: {
effect: {
player_use(card, player, target) {
@@ -2273,6 +2631,7 @@ const skills = {
},
},
},
+ */
},
dcbenshi: {
audio: 2,
@@ -2294,6 +2653,7 @@ const skills = {
},
content: function () {},
mod: {
+ /*
attackRangeBase: function (player, num) {
if (num !== "unchanged") return num;
var range = 1;
@@ -2309,8 +2669,9 @@ const skills = {
}
return range;
},
+ */
attackRange: function (player, num) {
- return num + 1;
+ if (!player.getEquips(1).length) return num + 1;
},
selectTarget: function (card, player, range) {
if (card.name == "sha") {
@@ -3342,7 +3703,7 @@ const skills = {
}
},
ai: {
- halfneg: true
+ neg: true,
},
},
xiongrao: {
@@ -5735,26 +6096,27 @@ const skills = {
player.logSkill("rehuoshui", targets);
event.targets = targets;
targets[0].addTempSkill("fengyin");
- if (targets.length < 2) event.goto(5);
+ if (targets.length < 2) event.goto(6);
} else event.finish();
"step 2";
- if (targets[1].countCards("h") == 0) event.goto(targets.length > 2 ? 4 : 5);
+ if (targets[1].countCards("h") == 0) event.goto(targets.length > 2 ? 4 : 6);
else targets[1].chooseCard("h", true, "交给" + get.translation(player) + "一张手牌");
"step 3";
if (result.bool) {
targets[1].give(result.cards, player);
}
+ "step 4";
if (targets.length < 3) {
- event.goto(5);
+ event.goto(6);
} else {
targets.splice(0, 2);
}
- "step 4";
+ "step 5";
var target = targets.shift();
var num = target.countCards("e");
if (num > 0) target.chooseToDiscard("e", true, num);
if (targets.length > 0) event.redo();
- "step 5";
+ "step 6";
game.delayx();
},
},
@@ -8681,6 +9043,31 @@ const skills = {
ai: {
jueqing: true,
},
+ init(player) {
+ game.addGlobalSkill("gangzhi_jueqing");
+ },
+ onremove(player) {
+ game.removeGlobalSkill("gangzhi_jueqing");
+ },
+ subSkill: {
+ jueqing: {
+ trigger: {player: "dieAfter"},
+ filter(event, player) {
+ return !game.hasPlayer(cur => cur.hasSkill("gangzhi"));
+ },
+ silent: true,
+ forceDie: true,
+ content() {
+ game.removeGlobalSkill("gangzhi_jueqing");
+ },
+ ai: {
+ jueqing: true,
+ skillTagFilter(player, tag, arg) {
+ if (tag === "jueqing") return arg && arg.hasSkill("gangzhi");
+ }
+ }
+ }
+ },
},
beizhan: {
trigger: { player: "phaseJieshuBegin" },
@@ -11568,47 +11955,58 @@ const skills = {
},
},
xinfu_xingzhao: {
- audio: true,
+ audio: 2,
group: ["xz_xunxun", "xinfu_xingzhao2", "xinfu_xingzhao3"],
+ trigger: {
+ player: "loseAfter",
+ global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
+ },
+ forced: true,
+ filter: function (event, player) {
+ if (
+ game.countPlayer(function (current) {
+ return current.isDamaged();
+ }) < 2
+ )
+ return false;
+ const evt = event.getl(player);
+ if (event.name == "equip" && event.player == player) return true;
+ return evt && evt.es.length;
+ },
+ getIndex(event, player) {
+ const evt = event.getl(player);
+ if (event.name == "equip" && event.player == player && evt && evt.es.length) return 2;
+ return 1;
+ },
+ content: function () {
+ player.draw();
+ },
+ derivation: "xz_xunxun",
mark: true,
intro: {
content: function (storage, player) {
var num = game.countPlayer(function (current) {
return current.isDamaged();
});
- var str = "暂无任何效果";
+ var str = "造成的伤害+1";
if (num >= 1) {
str = "视为拥有技能“恂恂”";
}
if (num >= 2) {
- str += ";使用装备牌时摸一张牌";
+ str += "
装备牌进入或离开你的装备区时摸一张牌";
}
if (num >= 3) {
- str += ";始终跳过弃牌阶段";
+ str += "
始终跳过弃牌阶段";
}
- if (num == 0 || num >= 4) {
- str += ";造成的伤害+1";
+ if (num >= 4) {
+ str += "
造成的伤害+1";
}
return str;
},
},
- trigger: {
- player: "useCard",
- },
- forced: true,
- filter: function (event, player) {
- if (get.type(event.card) != "equip") return false;
- var num = game.countPlayer(function (current) {
- return current.isDamaged();
- });
- return num >= 2;
- },
- content: function () {
- player.draw();
- },
},
xinfu_xingzhao2: {
- audio: true,
+ audio: "xinfu_xingzhao",
trigger: {
player: ["phaseJudgeBefore", "phaseDiscardBefore"],
},
diff --git a/character/sp2/sort.js b/character/sp2/sort.js
index 5c2448f80..65d8f07e3 100644
--- a/character/sp2/sort.js
+++ b/character/sp2/sort.js
@@ -14,7 +14,8 @@ const characterSort = {
sp_xuzhou: ["re_taoqian", "caosong", "zhangmiao", "qiuliju"],
sp_zhongyuan: ["re_hucheer", "re_zoushi", "caoanmin", "re_dongcheng"],
sp_xiaohu: ["haomeng", "yanfuren", "yanrou", "dc_zhuling"],
- sp_star: ["star_caoren", "star_yuanshu", "star_dongzhuo", "star_yuanshao", "star_zhangchunhua", "star_sunjian"],
+ sp_qunxiong: ["chezhou", "hansong", "matie"],
+ sp_star: ["star_caoren", "star_yuanshu", "star_dongzhuo", "star_yuanshao", "star_zhangchunhua", "star_sunjian", "star_zhangzhao"],
mini_qixian: ["mp_liuling"],
sp2_waitforsort: ["caobuxing", "re_maliang", "dc_jikang"],
};
@@ -34,6 +35,7 @@ const characterSortTranslate = {
sp_zhongyuan: "列传·中原狼烟",
sp_binglin: "兵临城下",
sp_xiaohu: "列传·虓虎悲歌",
+ sp_qunxiong: "列传·群雄伺动",
sp_fenghuo: "烽火连天",
sp_danqi: "千里单骑",
sp_star: "将星系列",
diff --git a/character/sp2/translate.js b/character/sp2/translate.js
index 980525913..fd63ebc6c 100644
--- a/character/sp2/translate.js
+++ b/character/sp2/translate.js
@@ -57,7 +57,7 @@ const translates = {
xz_xunxun: "恂恂",
xz_xunxun_info: "摸牌阶段,你可以观看牌堆顶的四张牌,然后将其中的两张牌置于牌堆顶,并将其余的牌以任意顺序置于牌堆底。",
xinfu_xingzhao: "兴棹",
- xinfu_xingzhao_info: "锁定技。若X≥1,你视为拥有技能〖恂恂〗。若X≥2,当你使用装备牌时,你摸一张牌。若X≥3,判定阶段或弃牌阶段开始时,你跳过此阶段。若X=0或X≥4,当你造成伤害时,此伤害+1(X为场上已受伤的角色数)。",
+ xinfu_xingzhao_info: "锁定技。若场上已受伤的角色数:≥1,你视为拥有技能〖恂恂〗;X≥2,有装备牌进入或离开你的装备区时,你摸一张牌;X≥3,判定阶段或弃牌阶段开始时,你跳过此阶段;为0或≥4,当你造成伤害时,此伤害+1。",
xinfu_xingzhao2: "兴棹",
xinfu_xingzhao2_info: "",
xinfu_xingzhao3: "兴棹",
@@ -485,9 +485,9 @@ const translates = {
dczuojian_info: "出牌阶段结束时,若你于此阶段使用过的牌数不小于体力值,你可以选择一项:1.令装备区牌数多于你的角色各摸一张牌;2.弃置装备区牌数少于你的角色各一张手牌。",
sunlang: "孙狼",
dctingxian: "铤险",
- dctingxian_info: "每回合限一次。当你使用【杀】指定最后一个目标后,你可以摸X张牌,然后令此【杀】对其中至多X个目标无效(X为你装备区的牌数+1)。",
+ dctingxian_info: "每回合限一次。当你使用【杀】指定最后一个目标后,你可以摸X张牌,然后可以令此【杀】对其中至多X个目标无效(X为你装备区的牌数+1)。",
dcbenshi: "奔矢",
- dcbenshi_info: "锁定技。①你的攻击范围+1。②你的攻击范围基数不受装备区内武器牌的影响。③由你使用的【杀】的牌面信息中的“使用目标”产生的规则改为“攻击范围内的所有角色”。",
+ dcbenshi_info: "锁定技。①若你未装备武器牌,则你的攻击范围+1。②由你使用的【杀】的牌面信息中的“使用目标”产生的规则改为“攻击范围内的所有角色”。",
sunhuan: "孙桓",
dcniji: "逆击",
dcniji_info: "①当你成为非装备牌的目标后,你可以摸一张牌,称为“逆击”。②一名角色的结束阶段,你可以使用一张“逆击”牌,然后弃置所有“逆击”牌。",
@@ -580,6 +580,27 @@ const translates = {
starruijun_info: "当你于出牌阶段首次使用牌指定其他角色为目标后,若目标角色数为1,你可以摸X张牌(X为你已损失的体力值+1)。直到此阶段结束,所有不为其的其他角色均不在你的攻击范围内,且当你对其造成伤害时,此伤害值改为Y(Y为你本回合上一次对其造成过的伤害值+1,至多为5)。",
stargangyi: "刚毅",
stargangyi_info: "锁定技。①你的回合内,若你本回合没有造成过伤害,你不能使用【桃】。②当你处于濒死状态时,以你为目标的【桃】或【酒】的回复值+1。",
+ star_zhangzhao: "星张昭",
+ star_zhangzhao_prefix: "星",
+ starzhongyan: "忠言",
+ starzhongyan_info: "出牌阶段限一次,你可展示牌堆顶三张牌,然后令一名角色将一张手牌与其中一张牌交换。然后若这些牌颜色相同,其回复1点体力或获得场上一张牌。然后若该角色不为你,你执行其未执行的一项。",
+ starjinglun: "经纶",
+ starjinglun_info: "每回合限一次,当你距离1以内的角色造成伤害后,你可以令其摸X张牌并对其发动〖忠言〗(X为其装备区的牌数)。",
+ chezhou: "车胄",
+ dcshefu: "慑伏",
+ dcshefu_info: "锁定技。你对其他角色/其他角色对你使用牌造成的伤害改为X(X为此牌对应的所有实体牌最近一次被伤害来源获得后至现在经过的轮次数之和)。",
+ dcpigua: "披挂",
+ dcpigua_info: "当你对一名其他角色造成超过1点伤害后,你可以获得其至多等同于游戏轮次的牌,这些牌本回合不计入你的手牌上限。",
+ hansong: "韩嵩",
+ dcyinbi: "隐避",
+ dcyinbi_info: "锁定技。①你的手牌上限与场上手牌上限最多的角色相同。②若没有角色手牌数与你相等,你使用牌无距离和次数限制。",
+ dcshuaiyan: "率言",
+ dcshuaiyan_info: "锁定技,其他角色手牌数变化后,若与你相等,你弃置其一张牌或摸一张牌。",
+ matie: "马铁",
+ dczhuiwang: "追亡",
+ dczhuiwang_info: "锁定技,你计算体力值小于等于你的角色的距离视为1。",
+ dcquxian: "驱险",
+ dcquxian_info: "出牌阶段开始时,你可以选择一名角色,若其在其他角色的攻击范围内,这些角色可依次对其使用一张【杀】。然后若其未以此法受到伤害,未使用【杀】的角色各失去X点体力(X为以此法使用【杀】的角色数量)。",
};
export default translates;
diff --git a/character/sp2/voices.js b/character/sp2/voices.js
index 7ff2f4a48..2abd108aa 100644
--- a/character/sp2/voices.js
+++ b/character/sp2/voices.js
@@ -325,7 +325,10 @@ export default {
"#sptunjiang1": "江夏冲要之地,孩儿愿往守之。",
"#sptunjiang2": "皇叔勿惊,吾与关将军已到。",
"#sp_liuqi:die": "父亲,孩儿来,见你了……",
- "#xinfu_xingzhao": "拿些上好的木料来。",
+ "#xinfu_xingzhao1": "拿些上好的木料来。",
+ "#xinfu_xingzhao2": "精挑细选,方能成百年之计。",
+ "#xz_xunxun1": "让我先探他一探。",
+ "#xz_xunxun2": "船,也不是一天就能造出来的。",
"#xf_tangzi:die": "偷工减料,要不得啊……",
"#xinfu_dianhu1": "就用你,给我军祭旗!",
"#xinfu_dianhu2": "预则立,不预则废!",
@@ -407,9 +410,6 @@ export default {
"#zhangu2": "雄狮搏兔,何须援乎?",
"#bmcanshi1": "是你,在召唤我吗?",
"#bmcanshi2": "这片土地的人,真是太有趣了。",
- "#xz_xunxun1": "精挑细选,方能成百年之计。",
- "#xz_xunxun2": "让我先探他一探。",
- "#xinfu_xingzhao2": "船,也不是一天就能造出来的。",
"#starruijun1": "三军夺锐,势不可挡。",
"#starruijun2": "士如钢锋,可破三属之甲。",
"#stargangyi1": "不见狼居胥,何妨马革裹尸。",
diff --git a/character/standard/characterReplace.js b/character/standard/characterReplace.js
index abf7368cb..325f042da 100644
--- a/character/standard/characterReplace.js
+++ b/character/standard/characterReplace.js
@@ -17,7 +17,7 @@ const characterReplaces = {
sp_machao: ["sp_machao", "dc_sp_machao", "jsrg_machao", "old_machao"],
zhugeliang: ["zhugeliang", "re_zhugeliang", "sb_zhugeliang", "ps2066_zhugeliang", "ps_zhugeliang"],
huangyueying: ["huangyueying", "re_huangyueying", "junk_huangyueying", "sb_huangyueying"],
- sunquan: ["sunquan", "re_sunquan", "sb_sunquan", "dc_sunquan"],
+ sunquan: ["sunquan", "re_sunquan", "sb_sunquan", "dc_sunquan", "xin_sunquan"],
zhouyu: ["zhouyu", "re_zhouyu", "dc_sb_zhouyu", "sb_zhouyu", "ps1062_zhouyu", "ps2080_zhouyu"],
luxun: ["luxun", "re_luxun", "jsrg_luxun"],
lvmeng: ["lvmeng", "re_lvmeng", "sb_lvmeng"],
diff --git a/character/standard/skill.js b/character/standard/skill.js
index 65b14037e..50d13ce5b 100644
--- a/character/standard/skill.js
+++ b/character/standard/skill.js
@@ -42,6 +42,7 @@ const skills = {
unique: true,
limited: true,
audio: "xiongyi",
+ enable: "phaseUse",
filterTarget: true,
selectTarget: [1, Infinity],
skillAnimation: true,
@@ -51,6 +52,7 @@ const skills = {
const targets = event.targets.sortBySeat();
let keep = true;
while (true) {
+ let stop = false;
for (const target of targets) {
let next = target
.chooseToUse(function (card) {
@@ -63,9 +65,13 @@ const skills = {
});
if (!keep) next.set("prompt2", "若你不使用,则结束此流程");
const result = await next.forResult();
- if (!result.bool && !keep) break;
- if (targets[targets.length - 1] == target && !keep) keep = true;
+ if (!result.bool && !keep) {
+ stop = true;
+ break;
+ }
}
+ if (keep) keep = false;
+ if (stop) break;
}
},
ai: {
@@ -231,6 +237,9 @@ const skills = {
player.popup("盗书");
game.log(player, "重置了技能", "#g【盗书】");
},
+ ai: {
+ combo: "stddaoshu"
+ },
},
//周处
stdxiongxia: {
@@ -240,6 +249,7 @@ const skills = {
selectCard: 2,
position: "hes",
viewAs: { name: "juedou" },
+ selectTarget: 2,
viewAsFilter(player) {
if (player.countCards("hes") < 2) return false;
},
@@ -486,7 +496,7 @@ const skills = {
threaten: 0.9,
effect: {
target: function (card, player, target) {
- if (player.hasSkillTag("jueqing")) return;
+ if (player.hasSkillTag("jueqing", false, target)) return;
if (player._stdjinjian_tmp) return;
const count = player.storage.counttrigger;
if (count && count.stdjinjian_player && count.stdjinjian_player > 0) return;
@@ -1877,8 +1887,10 @@ const skills = {
audioname2: {
old_guanzhang: "old_fuhun",
old_guanyu: "wusheng_re_guanyu",
+ guanzhang: "wusheng_guanzhang",
+ guansuo: "wusheng_guansuo",
},
- audioname: ["re_guanyu", "guanzhang", "jsp_guanyu", "guansuo", "re_guanzhang", "dc_jsp_guanyu"],
+ audioname: ["re_guanyu", "jsp_guanyu", "re_guanzhang", "dc_jsp_guanyu"],
enable: ["chooseToRespond", "chooseToUse"],
filterCard(card, player) {
if (get.zhu(player, "shouyue")) return true;
@@ -1950,10 +1962,11 @@ const skills = {
paoxiao: {
audio: 2,
firstDo: true,
- audioname: ["re_zhangfei", "guanzhang", "xiahouba"],
+ audioname: ["re_zhangfei", "xiahouba"],
audioname2: {
old_guanzhang: "old_fuhun",
dc_xiahouba: "paoxiao_xiahouba",
+ guanzhang: "paoxiao_guanzhang",
},
trigger: { player: "useCard1" },
forced: true,
@@ -3122,7 +3135,7 @@ const skills = {
trigger.source.chooseDrawRecover(true);
},
ai: {
- halfneg: true,
+ neg: true,
effect: {
target(card, player, target, current) {
if (card.name == "sha" && get.color(card) == "red") {
diff --git a/character/standard/translate.js b/character/standard/translate.js
index 0ca3e16df..2ffff3f57 100644
--- a/character/standard/translate.js
+++ b/character/standard/translate.js
@@ -208,8 +208,8 @@ const translates = {
stddaizui: "戴罪",
stddaizui_info: "锁定技,当你受到伤害后,你视为本轮未发动过〖盗书〗。",
stdxiongxia: "凶侠",
- stdxiongxia_info: "你可以将两张牌当作【决斗】使用。你以此法使用的【决斗】结算完毕后,若所有目标角色都受到了此牌造成的伤害,则〖凶侠〗于本回合失效。",
- stdhuizhan: "挥战",
+ stdxiongxia_info: "你可以将两张牌当作【决斗】对两名其他角色使用。你以此法使用的【决斗】结算完毕后,若所有目标角色都受到了此牌造成的伤害,则〖凶侠〗于本回合失效。",
+ stdhuizhan: "挥戟",
stdhuizhan_info: "你使用【杀】可以额外指定至多两个目标。若如此做,目标角色响应此【杀】时,其他目标角色可以代替其使用【闪】。",
stdmingfa: "明伐",
stdmingfa_info: "出牌阶段,你可以对一名体力值大于1的角色造成1点伤害,然后此技能失效直至其死亡或回复体力。",
diff --git a/character/tw/skill.js b/character/tw/skill.js
index 5517024d3..bf94d1736 100644
--- a/character/tw/skill.js
+++ b/character/tw/skill.js
@@ -274,7 +274,7 @@ const skills = {
let max = 0,
names = ["huogong", "tiesuo", "wuzhong"].filter(name => {
if (player.getStorage("twcairu_used").includes(name)) return false;
- return event.filterCard({ name }, player, event);
+ return player.hasValueTarget(name ,true, true);
});
if (!names.length) return 0;
names = names.map(namex => ({ name: namex }));
@@ -1942,8 +1942,7 @@ const skills = {
.set(
"goon",
(function () {
- var d1 = true;
- if (player.hasSkill("jueqing") || player.hasSkill("gangzhi")) d1 = false;
+ var d1 = false;
if (
!target.mayHaveShan(
player,
@@ -1962,15 +1961,7 @@ const skills = {
true
)
) {
- if (!target.hasSkill("gangzhi")) d1 = false;
- if (
- !target.hasSkillTag("filterDamage", null, {
- player: player,
- card: trigger.card,
- }) &&
- get.attitude(player, target) < 0
- )
- return true;
+ if (get.attitude(player, target) < 0 && !player.hasSkillTag("jueqing", false, target)) return true;
}
if (d1) return get.damageEffect(player, player, player) > 0;
return false;
@@ -3258,7 +3249,7 @@ const skills = {
player.addMark("twshoushou_plus", 1, false);
},
ai: {
- halfneg: true,
+ neg: true,
},
subSkill: {
damage: {
@@ -4355,6 +4346,7 @@ const skills = {
target.damage();
},
ai: {
+ combo: "twjuntun",
expose: 0.25,
order: 8,
result: {
@@ -4439,6 +4431,9 @@ const skills = {
},
},
},
+ ai: {
+ combo: "twjuntun"
+ },
},
//蒋济
twjichou: {
@@ -8327,6 +8322,7 @@ const skills = {
forced: true,
content: function () {
trigger.directHit.addArray(game.players);
+ game.log(trigger.card, "不可被响应");
},
ai: { directHit_ai: true },
},
@@ -13715,8 +13711,6 @@ const skills = {
"goon",
(function () {
if (get.attitude(target, player) < 0) return false;
- var d1 = true;
- if (trigger.player.hasSkill("jueqing") || trigger.player.hasSkill("gangzhi")) d1 = false;
for (var target of trigger.targets) {
if (
!target.mayHaveShan(
@@ -13736,18 +13730,19 @@ const skills = {
true
)
) {
- if (!target.hasSkill("gangzhi")) d1 = false;
if (
+
+ get.attitude(player, target) < 0 &&
+ !trigger.player.hasSkillTag("jueqing", false, target) &&
!target.hasSkillTag("filterDamage", null, {
player: trigger.player,
card: trigger.card,
- }) &&
- get.attitude(player, target) < 0
+ })
)
return true;
}
}
- return d1;
+ return false;
})()
);
if (!event.target.isUnderControl(true) && !event.target.isOnline()) game.delayx();
@@ -16107,9 +16102,8 @@ const skills = {
return event.card.name == "sha" && (event.player == player || player.inRange(event.player)) && player.countCards("he") > 0;
},
checkx(event, player) {
- let d1 = true,
+ let d1 = false,
e = false;
- if (event.player.hasSkill("jueqing") || event.player.hasSkill("gangzhi")) d1 = false;
for (let tar of event.targets) {
if (event.card.name == "sha") {
if (
@@ -16130,13 +16124,14 @@ const skills = {
true
)
) {
- if (!tar.hasSkill("gangzhi")) d1 = false;
if (
+ !event.player.hasSkillTag("jueqing", false, tar) &&
!tar.hasSkillTag("filterDamage", null, {
player: event.player,
card: event.card,
})
) {
+ d1 = true;
let att = get.attitude(_status.event.player, tar);
if (att > 0) return false;
if (att < 0) e = true;
diff --git a/character/xianding/character.js b/character/xianding/character.js
index fa813f3ca..236943271 100644
--- a/character/xianding/character.js
+++ b/character/xianding/character.js
@@ -1,4 +1,12 @@
const characters = {
+ zhupeilan: ["female", "wu", 3, ["dccilv", "dctongdao"]],
+ dc_sb_zhangxiu: ["male", "qun", 4, ["dcsbfuxi", "dcsbhaoyi"]],
+ dc_sb_guanping: ["male", "shu", 4, ["dcsbwuwei"]],
+ dc_sb_caoang: ["male", "wei", 4, ["dcsbfengmin", "dcsbzhiwang", "dcsbjueying"]],
+ dc_caoshuang: ["male", "wei", 4, ["dcjianzhuan", "dcfanshi"]],
+ dc_simashi: ["male", "wei", 3, ["dcsanshi", "dczhenrao", "dcchenlve"]],
+ dc_wangling: ["male", "wei", 4, ["dcjichou", "dcmouli"], ["clan:太原王氏"]],
+ dc_jiangji: ["male", "wei", 3, ["dcshiju", "dcyingshi"]],
dc_sb_zhugejin: ["male", "wu", 3, ["dcsbtaozhou", "dcsbhoude"]],
dc_sb_jiaxu: ["male", "qun", 3, ["dcsbsushen", "dcsbfumou"]],
guanyue: ["male", "shu", 4, ["dcshouzhi", "dcfenhui"]],
diff --git a/character/xianding/characterReplace.js b/character/xianding/characterReplace.js
index 6b585cbe4..f03e5d3c3 100644
--- a/character/xianding/characterReplace.js
+++ b/character/xianding/characterReplace.js
@@ -14,6 +14,8 @@ const characterReplaces = {
caomao: ["caomao", "mb_caomao"],
sp_zhenji: ["sp_zhenji", "jsrg_zhenji"],
zhugejin: ["zhugejin", "dc_sb_zhugejin"],
+ caoang: ["caoang", "dc_sb_caoang"],
+ zhangxiu: ["zhangxiu", "dc_sb_zhangxiu"],
};
export default characterReplaces;
diff --git a/character/xianding/index.js b/character/xianding/index.js
index 16517baa9..b84cab42b 100644
--- a/character/xianding/index.js
+++ b/character/xianding/index.js
@@ -22,7 +22,7 @@ game.import("character", function () {
characterSubstitute: {
dc_sb_simayi: [],
dc_sb_zhouyu: [],
- //dc_sb_lusu: [],
+ dc_sb_lusu: [],
},
characterFilter: { ...characterFilters },
characterTitle: {
diff --git a/character/xianding/intro.js b/character/xianding/intro.js
index 5bbc127bb..4782d2b20 100644
--- a/character/xianding/intro.js
+++ b/character/xianding/intro.js
@@ -55,6 +55,7 @@ const characterIntro = {
caoyi: "曹轶,游卡桌游旗下产品《三国杀》原创角色。设定上为曹纯所收养的孙女,从小受到曹纯的教导,在军营中长大,性情坚毅有担当,军事谋略丰富,战斗能力超强。曹轶喜欢美食,特别是甜食,并且擅长制作各种点心。她身边跟随的雪白小老虎是曹纯在她及笄时送的生辰礼物,希望她如小老虎一样,英勇无畏。曹轶与曹婴交好,两人以姐妹相称。曹轶成年后继承祖父衣钵,接手精锐部队“虎豹骑”,成为新的虎豹骑的统领者。",
huzun: "胡遵(?~256年),安定临泾(今甘肃省镇原县)人,三国时期曹魏大臣,官至卫将军,封阴密侯。出身安定胡氏。历任征东将军、征东大将军、卫将军等职。早年由张既征辟。后追随司马懿,参与平定匈奴胡薄居姿职叛乱、抵御诸葛亮北伐、平定公孙渊叛乱。嘉平四年(252年),作为曹魏三征之一的征东将军,主持征讨东吴,被诸葛恪击败。正元元年(255年)参与平定淮南三叛的第二叛毌丘俭、文钦之乱,事后升任卫将军。甘露元年(256年)秋七月己卯去世,追赠车骑将军。",
guanyue: "关樾,传说记载之人物,声称是关羽之孙,关平长子。未见载于正史,仅记载于清朝地方志以及传说。清·《江陵县志》:“娶镇东将军女赵氏。生子樾,世居江陵。”。清·《关氏宗谱·江陵县儒学册结》:“平子樾,因守祖、父陵墓遂家于荆州焉,此荆州之关氏所由来也。”",
+ zhupeilan: "景皇后朱氏(234年―265年),吴郡吴县(今江苏省苏州市)人,吴景帝孙休的皇后,野史记载其名为朱佩兰。骠骑将军朱据与朱公主的独生女,吴末帝孙皓的表姐和叔母。出身江南四大姓之一吴郡朱氏。赤乌末年,与孙休成婚,永安元年(258年),孙休继位,封为夫人,永安五年(262年),被立为皇后。孙休去世后为太后,甘露元年秋(265年)被孙皓逼杀,葬于定陵。",
};
export default characterIntro;
diff --git a/character/xianding/skill.js b/character/xianding/skill.js
index 7f4038e37..311e9b1b3 100644
--- a/character/xianding/skill.js
+++ b/character/xianding/skill.js
@@ -3,6 +3,515 @@ import cards from "../sp2/card.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
+ //朱佩兰
+ dccilv: {
+ audio: 2,
+ trigger: { target: "useCardToTargeted" },
+ filter(event, player) {
+ return get.type(event.card) == "trick" && player.getStorage("dccilv").length < 3;
+ },
+ async content(event, trigger, player) {
+ await player.draw(3 - player.getStorage("dccilv").length);
+ if (player.countCards("h") > player.maxHp) {
+ let result,
+ list = ["无效", "防伤", "获得"].filter(i => !player.getStorage("dccilv").includes(i));
+ if (list.length == 1) result = { control: list[0] };
+ else
+ result = await player
+ .chooseControl(list)
+ .set("prompt", "辞虑:选择执行并移去一项")
+ .set("ai", () => {
+ const player = get.event("player"),
+ trigger = get.event().getTrigger(),
+ card = trigger.card;
+ let controls = get.event("controls").slice();
+ if (controls.includes("防伤")) {
+ if (get.tag(card, "damage")) return "防伤";
+ else controls.remove("防伤");
+ }
+ if (get.effect(player, trigger.card, trigger.player, player) < 0 && controls.includes("无效")) return "无效";
+ return controls[controls.length - 1];
+ })
+ .forResult();
+ const choice = result.control;
+ player.popup(choice);
+ game.log(player, "选择了", "#y" + choice);
+ switch (choice) {
+ case "无效":
+ trigger.getParent().excluded.add(player);
+ game.log(trigger.card, "对", player, "无效");
+ break;
+ case "防伤":
+ player.addTempSkill("dccilv_effect");
+ player.markAuto("dccilv_effect", [trigger.card]);
+ break;
+ case "获得":
+ player
+ .when({ global: "useCardAfter" })
+ .filter(evt => evt == trigger.getParent())
+ .then(() => {
+ const cards = (trigger.cards || []).filterInD();
+ if (cards.length) player.gain(cards, "gain2");
+ });
+ break;
+ }
+ player.markAuto("dccilv", [choice]);
+ }
+ },
+ mark: true,
+ intro: {
+ markcount: storage => 3 - (storage || []).length,
+ content: storage => ((storage || []).length ? "已移去了$项" : "暂未移去任何项"),
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ trigger: { player: "damageBegin4" },
+ filter(event, player) {
+ const evt = event.getParent(2);
+ return evt && evt.name == "useCard" && player.getStorage("dccilv_effect").includes(evt.card);
+ },
+ forced: true,
+ content() {
+ trigger.cancel();
+ },
+ ai: {
+ effect: {
+ target(card, player, target) {
+ if (player.getStorage("dccilv_effect").includes(card)) return "zeroplayertarget";
+ },
+ },
+ },
+ },
+ },
+ },
+ dctongdao: {
+ unique: true,
+ limited: true,
+ trigger: { player: "dying" },
+ skillAnimation: true,
+ animationColor: "fire",
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(get.prompt2("dctongdao"))
+ .set("ai", target => {
+ const player = get.event("player");
+ if (player.hp + player.countCards("hs", card => player.canSaveCard(card, player)) > 0) return target == player ? 1 : 0;
+ return target.hp + 114514;
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ const target = event.targets[0];
+ player.awakenSkill("dctongdao");
+ const removeSkills = target.getSkills(null, false, false).filter(i => {
+ const info = get.info(i);
+ return !info || !info.charlotte;
+ });
+ if (removeSkills.length) target.removeSkill(removeSkills);
+ const gainSkills = target.getStockSkills(true, true).filter(i => {
+ const info = get.info(i);
+ if (info && info.zhuSkill && !player.isZhu2()) return false;
+ return !info || !info.charlotte;
+ });
+ if (gainSkills.length) {
+ //抽象
+ //混沌初开——牢戏
+ Object.keys(target.storage)
+ .filter(i => gainSkills.some(skill => i.startsWith(skill)))
+ .forEach(storage => delete target.storage[storage]);
+ target.addSkill(gainSkills);
+ const suffixs = ["used", "round", "block", "blocker"];
+ for (const skill of gainSkills) {
+ const info = get.info(skill);
+ if (typeof info.usable == "number") {
+ if (target.hasSkill("counttrigger") && target.storage.counttrigger[skill] && target.storage.counttrigger[skill] >= 1) {
+ delete target.storage.counttrigger[skill];
+ }
+ if (typeof get.skillCount(skill) == "number" && get.skillCount(skill) >= 1) {
+ delete target.getStat("skill")[skill];
+ }
+ }
+ if (info.round && target.storage[skill + "_roundcount"]) {
+ delete target.storage[skill + "_roundcount"];
+ }
+ if (target.storage[`temp_ban_${skill}`]) {
+ delete target.storage[`temp_ban_${skill}`];
+ }
+ if (target.awakenedSkills.includes(skill)) {
+ target.restoreSkill(skill);
+ }
+ for (const suffix of suffixs) {
+ if (target.hasSkill(skill + "_" + suffix)) {
+ target.removeSkill(skill + "_" + suffix);
+ }
+ }
+ }
+ }
+ if (target != player && target.hp > player.hp) {
+ await player.recoverTo(target.hp);
+ }
+ },
+ },
+ //张绣
+ dcsbfuxi: {
+ audio: 2,
+ trigger: { global: "phaseUseBegin" },
+ filter(event, player) {
+ const target = event.player;
+ if (!player.countCards("he") && !target.countCards("he") && !player.canUse(new lib.element.VCard({ name: "sha" }), target, false)) return false;
+ return event.player != player && event.player.isMaxHandcard();
+ },
+ async cost(event, trigger, player) {
+ const target = trigger.player,
+ str = get.translation(target);
+ let result;
+ if (!player.countCards("he")) {
+ result = await player
+ .chooseBool(get.prompt("dcsbfuxi", target), "弃置" + str + "的一张牌,然后视为对其使用一张【杀】")
+ .set("choice", get.effect(target, { name: "guohe_copy2" }, player, player) + get.effect(target, new lib.element.VCard({ name: "sha" }), player, player) > 0)
+ .forResult();
+ result.index = 1;
+ } else if (!target.countCards("he") && !player.canUse(new lib.element.VCard({ name: "sha" }), target, false)) {
+ result = await player
+ .chooseBool(get.prompt("dcsbfuxi", target), "交给" + str + "一张牌,然后摸两张牌")
+ .set("choice", get.attitude(player, target) > 0 || player.hasCard(card => card.name == "du", "h"))
+ .forResult();
+ result.index = 0;
+ } else {
+ result = await player
+ .chooseControl("给牌", "出杀", "cancel2")
+ .set("choiceList", ["交给" + str + "一张牌,然后摸两张牌", "弃置" + str + "的一张牌,然后视为对其使用一张【杀】"])
+ .set("ai", () => {
+ const player = get.event("player"),
+ target = get.event("target");
+ const num = get.effect(target, { name: "guohe_copy2" }, player, player) + get.effect(target, new lib.element.VCard({ name: "sha" }), player, player);
+ if (num <= 0 && get.attitude(player, target) < 0) return "cancel2";
+ return get.attitude(player, target) >= 0 ? 0 : 1;
+ })
+ .set("target", target)
+ .forResult();
+ result.bool = result.control != "cancel2";
+ }
+ if (result.bool) {
+ result.targets = [target];
+ result.cost_data = result.index;
+ }
+ event.result = result;
+ },
+ async content(event, trigger, player) {
+ const target = trigger.player;
+ if (event.cost_data == 0) {
+ await player.chooseToGive(target, "he", true);
+ await player.draw(2);
+ } else {
+ await player.discardPlayerCard(target, "he", true);
+ const sha = new lib.element.VCard({ name: "sha" });
+ if (player.canUse(sha, target, false)) {
+ await player.useCard(sha, target, false);
+ }
+ }
+ },
+ },
+ dcsbhaoyi: {
+ audio: 2,
+ trigger: { player: "phaseJieshuBegin" },
+ filter(event, player) {
+ return lib.skill.dcsbhaoyi.getCards().length;
+ },
+ frequent: true,
+ prompt(event, player) {
+ return get.prompt("dcsbhaoyi") + "(可获得" + get.translation(lib.skill.dcsbhaoyi.getCards()) + ")";
+ },
+ async content(event, trigger, player) {
+ let cardx = lib.skill.dcsbhaoyi.getCards();
+ await player.gain(cardx, "gain2");
+ cardx = cardx.filter(i => get.owner(i) == player && get.position(i) == "h");
+ if (!cardx.length) return;
+ if (_status.connectMode) game.broadcastAll(() => (_status.noclearcountdown = true));
+ let given_map = [];
+ while (player.hasCard(card => cardx.includes(card) && !card.hasGaintag("olsujian_given"), "h")) {
+ const {
+ result: { bool, cards, targets },
+ } = await player
+ .chooseCardTarget({
+ filterCard(card, player) {
+ return get.event("cards").includes(card) && !card.hasGaintag("olsujian_given");
+ },
+ selectCard: [1, Infinity],
+ position: "h",
+ filterTarget: lib.filter.notMe,
+ prompt: "豪意:请选择要分配的卡牌和目标",
+ ai1(card) {
+ return !ui.selected.cards.length && card.name == "du" ? 1 : 0;
+ },
+ ai2(target) {
+ const player = get.event("player");
+ const card = ui.selected.cards[0];
+ if (card) return get.value(card, target) * get.attitude(player, target);
+ return 0;
+ },
+ })
+ .set("cards", cardx);
+ if (bool) {
+ const target = targets[0];
+ if (given_map.some(i => i[0] == target)) {
+ given_map[given_map.indexOf(given_map.find(i => i[0] == target))][1].addArray(cards);
+ } else given_map.push([target, cards]);
+ player.addGaintag(cards, "olsujian_given");
+ } else break;
+ }
+ if (_status.connectMode) {
+ game.broadcastAll(() => {
+ delete _status.noclearcountdown;
+ game.stopCountChoose();
+ });
+ }
+ if (given_map.length) {
+ await game
+ .loseAsync({
+ gain_list: given_map,
+ player: player,
+ cards: given_map.slice().map(list => list[1]),
+ giver: player,
+ animate: "giveAuto",
+ })
+ .setContent("gaincardMultiple");
+ }
+ },
+ getCards() {
+ let cards = [],
+ targets = game.players.slice().concat(game.dead.slice());
+ for (const target of targets) {
+ const history = target.getHistory("lose", evt => evt.position == ui.discardPile);
+ if (history.length) {
+ for (const evt of history) cards.addArray(evt.cards2.filterInD("d"));
+ }
+ }
+ const historyx = game.getGlobalHistory("cardMove", evt => evt.name == "cardsDiscard");
+ if (historyx.length) {
+ for (const evtx of historyx) cards.addArray(evtx.cards.filterInD("d"));
+ }
+ for (const target of targets) {
+ const history = target.getHistory(
+ "useCard",
+ evt =>
+ (evt.cards || []).length &&
+ target.getHistory("sourceDamage", evtx => {
+ return evtx.card && evtx.card == evt.card;
+ }).length
+ );
+ if (history.length) {
+ for (const evt of history) cards.removeArray(evt.cards.filterInD("d"));
+ }
+ }
+ return cards.filter(card => get.tag(card, "damage"));
+ },
+ },
+ //关平
+ dcsbwuwei: {
+ audio: 2,
+ enable: "phaseUse",
+ filter(event, player) {
+ const count = player.getStat("skill").dcsbwuwei;
+ if (count && count > player.countMark("dcsbwuwei_count")) return false;
+ const colors = player.getCards("h").reduce((list, card) => list.add(get.color(card)), []);
+ return colors.some(color => event.filterCard(get.autoViewAs(lib.skill.dcsbwuwei.viewAs, player.getCards("h", { color: color })), player, event));
+ },
+ viewAs: { name: "sha", storage: { dcsbwuwei: true } },
+ locked: false,
+ mod: {
+ targetInRange(card) {
+ if (card.storage && card.storage.dcsbwuwei) return true;
+ },
+ cardUsable(card, player, num) {
+ if (card.storage && card.storage.dcsbwuwei) return Infinity;
+ },
+ },
+ filterCard: () => false,
+ selectCard: -1,
+ async precontent(event, _, player) {
+ let colors = player.getCards("h").reduce((list, card) => list.add(get.color(card)), []),
+ evt = event.getParent();
+ colors = colors.filter(color => evt.filterCard(get.autoViewAs(lib.skill.dcsbwuwei.viewAs, player.getCards("h", { color: color })), player, evt));
+ colors = colors.map(color => (color == "none" ? "none2" : color));
+ const result = await player.chooseControl(colors, "cancel2").set("prompt", "武威:将一种颜色的所有手牌当作【杀】使用").forResult();
+ const color = result.control == "none2" ? "none" : result.control;
+ if (color == "cancel2") {
+ evt.goto(0);
+ return;
+ }
+ player.addTempSkill("dcsbwuwei_effect");
+ event.result.cards = player.getCards("h", { color: color });
+ event.result.card.cards = player.getCards("h", { color: color });
+ },
+ ai: {
+ order(item, player) {
+ return get.order({ name: "sha" }, player) - 0.001;
+ },
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ trigger: { player: "useCard" },
+ filter(event, player) {
+ return (event.card.storage || {}).dcsbwuwei && (event.cards || []).length;
+ },
+ forced: true,
+ popup: false,
+ async content(event, trigger, player) {
+ let result,
+ types = trigger.cards.reduce((list, card) => list.add(get.type(card, player)), []);
+ if (types.length >= 3) {
+ result = { bool: true, links: [0, 1, 2] };
+ } else {
+ result = await player
+ .chooseButton(["武威:请选择" + get.cnNumber(types.length) + "项执行", [["摸一张牌", "令目标角色本回合非锁定技失效", "令本回合〖武威〗可发动次数+1"].map((item, i) => [i, item]), "textbutton"]])
+ .set("forced", true)
+ .set("selectButton", types.length)
+ .set("ai", button => {
+ return [1, 3, 2].slice(0, get.event("selectButton")).includes(button.link) ? 1 : 0;
+ })
+ .forResult();
+ }
+ if (result.bool) {
+ result.links.sort((a, b) => a - b);
+ for (const i of result.links) {
+ game.log(player, "选择了", "#g【武威】", "的", "#y第" + get.cnNumber(i + 1, true) + "项");
+ }
+ if (result.links.includes(0)) await player.draw();
+ if (result.links.includes(1)) {
+ for (const target of trigger.targets || []) {
+ target.addTempSkill("fengyin");
+ }
+ }
+ if (result.links.includes(2)) {
+ player.addTempSkill("dcsbwuwei_count");
+ player.addMark("dcsbwuwei_count", 1, false);
+ }
+ if (result.links.length == 3) {
+ trigger.baseDamage++;
+ game.log(trigger.card, "造成的伤害", "#y+1");
+ }
+ }
+ },
+ },
+ count: {
+ charlotte: true,
+ onremove: true,
+ intro: { content: "本回合〖武威〗可发动次数+#" },
+ },
+ },
+ },
+ //曹昂
+ dcsbfengmin: {
+ audio: 2,
+ trigger: { global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"] },
+ filter(event, player) {
+ const target = _status.currentPhase;
+ if (
+ !target ||
+ !target.isIn() ||
+ !Array.from({ length: 5 })
+ .map((_, i) => i + 1)
+ .reduce((sum, i) => sum + target.countEmptySlot(i), 0)
+ )
+ return false;
+ const evt = event.getl(target);
+ return evt && evt.player == target && (evt.es || []).length;
+ },
+ forced: true,
+ logTarget: () => _status.currentPhase,
+ async content(event, trigger, player) {
+ player.addMark("dcsbfengmin", 1, false);
+ const target = _status.currentPhase;
+ await player.draw(
+ Array.from({ length: 5 })
+ .map((_, i) => i + 1)
+ .reduce((sum, i) => sum + target.countEmptySlot(i), 0)
+ );
+ if (player.countMark("dcsbfengmin") > player.getDamagedHp()) {
+ player.tempBanSkill("dcsbfengmin");
+ }
+ },
+ intro: { content: "本局游戏已发动过#次此技能" },
+ },
+ dcsbzhiwang: {
+ audio: 2,
+ trigger: { player: "dying" },
+ filter(event, player) {
+ const evt = event.getParent(),
+ evtx = event.getParent(3);
+ if (!evt || evt.name != "damage" || !evtx || evtx.name != "useCard") return false;
+ return game.hasPlayer(target => target != player);
+ },
+ usable: 1,
+ async cost(event, trigger, player) {
+ event.result = await player
+ .chooseTarget(get.prompt("dcsbzhiwang"), lib.filter.notMe)
+ .set("ai", target => {
+ return get.attitude(get.event("player"), target);
+ })
+ .forResult();
+ },
+ async content(event, trigger, player) {
+ if (trigger.source) delete trigger.source;
+ if (trigger.getParent().source) delete trigger.getParent().source;
+ event.targets[0].addTempSkill("dcsbzhiwang_effect");
+ event.targets[0].markAuto("dcsbzhiwang_effect", [player]);
+ },
+ subSkill: {
+ effect: {
+ charlotte: true,
+ onremove: true,
+ trigger: { global: "phaseEnd" },
+ forced: true,
+ popup: false,
+ async content(event, trigger, player) {
+ let cards = game
+ .getGlobalHistory("everything", evt => {
+ if (evt.name != "dying") return false;
+ if (!player.getStorage("dcsbzhiwang_effect").includes(evt.player)) return false;
+ const evtx = evt.getParent(3);
+ return (evtx.cards || []).someInD("d");
+ })
+ .reduce((cards, evt) => cards.addArray(evt.getParent(3).cards.filterInD("d")), []);
+ while (cards.length) {
+ const result = await player
+ .chooseButton(["质亡:是否使用其中的一张牌?", cards])
+ .set("filterButton", button => {
+ return get.event("player").hasUseTarget(button.link, false);
+ })
+ .set("ai", button => {
+ if (button.link.name == "jiu") return 10;
+ return get.event("player").getUseValue(button.link);
+ })
+ .forResult();
+ if (result.bool) {
+ const card = result.links[0];
+ cards.remove(card);
+ player.$gain2(card, false);
+ await game.asyncDelayx();
+ await player.chooseUseTarget(true, card, false);
+ }
+ }
+ },
+ intro: { content: "本回合结束时,可以使用令$进入濒死的牌" },
+ },
+ },
+ },
+ dcsbjueying: {
+ audio: 2,
+ trigger: { player: "damageBegin4" },
+ filter(event, player) {
+ const cards = player.getEquips("jueying");
+ return cards.length && cards.every(card => lib.filter.cardDiscardable(card, player));
+ },
+ content() {
+ player.discard(player.getEquips("jueying"));
+ trigger.cancel();
+ },
+ },
//诸葛瑾
dcsbtaozhou: {
audio: 2,
@@ -456,7 +965,7 @@ const skills = {
return delt < 0 || (delt > 0 && player.countCards("h"));
},
locked(skill, player) {
- return player && player.storage.dcshouzhi_modified;
+ return !(player && player.storage.dcshouzhi_modified);
},
derivation: ["dcshouzhi_modified"],
onremove: ["dcshouzhi_modified"],
@@ -798,6 +1307,7 @@ const skills = {
subSkill: {
g: {
audio: "dcwuyou",
+ forceaudio: true,
enable: "phaseUse",
usable: 1,
filter(event, player) {
@@ -934,6 +1444,10 @@ const skills = {
if (!card.cards) return;
if (card.cards.some(card => card.hasGaintag("dcwuyou_transfer"))) return Infinity;
},
+ targetInRange(card, player) {
+ if (!card.cards) return;
+ if (card.cards.some(card => card.hasGaintag("dcwuyou_transfer"))) return true;
+ },
},
},
},
@@ -1049,11 +1563,11 @@ const skills = {
result: {
player(player) {
const enemies = game.filterPlayer(current => {
- return get.rawAttitude(player, current) < 0 && get.attitude(player, current) >= 0;
- }),
- knownEnemies = game.filterPlayer(current => {
- return get.attitude(player, current) < 0;
- });
+ return (!get.rawAttitude || get.rawAttitude(player, current) < 0) && get.attitude(player, current) >= 0;
+ }),
+ knownEnemies = game.filterPlayer(current => {
+ return get.attitude(player, current) < 0;
+ });
if ((!knownEnemies.length && player.countCards("e") > 1) || (player.getHp() > 3 && enemies.length > 0 && knownEnemies.length < 2 && knownEnemies.length < enemies.length && !knownEnemies.some(enemy => get.attitude(player, enemy) <= -9))) return 0;
const val1 = game
.filterPlayer()
@@ -2914,8 +3428,7 @@ const skills = {
yield player.logSkill("dcsbmengmou", target);
player.addTempSkill("dcsbmengmou_" + (storage || false));
player.changeZhuanhuanji("dcsbmengmou");
- //鲁肃暂时没有另一张原画(悲
- //player.changeSkin("dcsbmengmou", "dc_sb_lusu" + (player.storage.dcsbmengmou ? "_shadow" : ""));
+ player.changeSkin("dcsbmengmou", "dc_sb_lusu" + (player.storage.dcsbmengmou ? "_shadow" : ""));
while (num > 0) {
num--;
var result2;
@@ -2983,8 +3496,7 @@ const skills = {
check: () => Math.random() > 0.5,
content() {
player.changeZhuanhuanji("dcsbmengmou");
- //鲁肃暂时没有另一张原画(悲
- //player.changeSkin("dcsbmengmou", "dc_sb_lusu" + (player.storage.dcsbmengmou ? "_shadow" : ""));
+ player.changeSkin("dcsbmengmou", "dc_sb_lusu" + (player.storage.dcsbmengmou ? "_shadow" : ""));
},
},
},
@@ -3700,7 +4212,7 @@ const skills = {
ai: {
effect: {
target: function (card, player, target) {
- if (target.countCards("h") > target.getHp() || player.hasSkillTag("jueqing")) return;
+ if (target.countCards("h") > target.getHp() || player.hasSkillTag("jueqing", false, target)) return;
if (player._dcxiongmu_temp) return;
if (_status.event.getParent("useCard", true) || _status.event.getParent("_wuxie", true)) return;
if (get.tag(card, "damage")) {
@@ -12994,7 +13506,7 @@ const skills = {
threaten: 0.9,
effect: {
target: function (card, player, target) {
- if (player.hasSkillTag("jueqing")) return;
+ if (player.hasSkillTag("jueqing", false, target)) return;
//if(target.hujia) return;
if (player._jinjian_tmp) return;
if (_status.event.getParent("useCard", true) || _status.event.getParent("_wuxie", true)) return;
diff --git a/character/xianding/sort.js b/character/xianding/sort.js
index d835acbee..3b6a9394d 100644
--- a/character/xianding/sort.js
+++ b/character/xianding/sort.js
@@ -2,7 +2,7 @@ const characterSort = {
sp2_huben: ["chendong", "wangshuang", "wenyang", "re_liuzan", "dc_huangzu", "wulan", "leitong", "chentai", "dc_duyu", "dc_wangjun", "dc_xiahouba", "old_huangfusong", "huzun"],
sp2_shengun: ["puyuan", "guanlu", "gexuan", "wufan", "re_zhangbao", "dukui", "zhaozhi", "zhujianping", "dc_zhouxuān", "zerong"],
sp2_bizhe: ["dc_luotong", "dc_wangchang", "chengbing", "dc_yangbiao", "ruanji", "cuimao"],
- sp2_huangjia: ["caomao", "liubian", "dc_liuyu", "quanhuijie", "dingshangwan", "yuanji", "xielingyu", "sunyu", "ganfurenmifuren", "dc_ganfuren", "dc_mifuren", "dc_shixie", "caofang"],
+ sp2_huangjia: ["caomao", "liubian", "dc_liuyu", "quanhuijie", "dingshangwan", "yuanji", "xielingyu", "sunyu", "ganfurenmifuren", "dc_ganfuren", "dc_mifuren", "dc_shixie", "caofang", "zhupeilan"],
sp2_zhangtai: ["guozhao", "fanyufeng", "ruanyu", "yangwan", "re_panshu"],
sp2_jinse: ["caojinyu", "re_sunyi", "re_fengfangnv", "caohua", "laiyinger", "zhangfen", "zhugeruoxue", "caoxian", "dc_qinghegongzhu", "zhugemengxue"],
sp2_yinyu: ["zhouyi", "luyi", "sunlingluan", "caoyi"],
@@ -14,7 +14,10 @@ const characterSort = {
sp2_gaoshan: ["wanglang", "liuhui", "zhangjian"],
sp2_wumiao: ["wu_zhugeliang", "wu_luxun", "wu_guanyu"],
sp2_mouding: ["dc_sb_jiaxu", "dc_sb_lusu", "dc_sb_zhouyu", "dc_sb_simayi"],
- sp2_zijing: ["dc_sb_zhugejin"],
+ sp2_zhonghu: ["dc_jiangji", "dc_wangling", "dc_simashi", "dc_caoshuang"],
+ sp2_zijing: ["dc_sb_zhugejin", "dc_sb_guanping"],
+ sp2_dushi: ["dc_sb_caoang", "dc_sb_zhangxiu"],
+ sp2_waitingforsort: [],
};
const characterSortTranslate = {
@@ -33,7 +36,10 @@ const characterSortTranslate = {
sp2_gaoshan: "高山仰止",
sp2_qifu: "祈福",
sp2_mouding: "谋定天下",
+ sp2_zhonghu: "冢虎狼顾",
sp2_zijing: "子敬邀刀",
+ sp2_dushi: "毒士鸩计",
+ sp2_waitingforsort: "等待分包",
};
export { characterSort, characterSortTranslate };
diff --git a/character/xianding/translate.js b/character/xianding/translate.js
index f62bcc3e4..7c5828669 100644
--- a/character/xianding/translate.js
+++ b/character/xianding/translate.js
@@ -607,6 +607,37 @@ const translates = {
dcsbhoude_info: "当你于其他角色的出牌阶段内首次成为红色【杀】/黑色普通锦囊牌的目标后,你可以弃置你/其的一张牌,令此牌对你无效。",
dcsbzijin: "自矜",
dcsbzijin_info: "锁定技。①你不能成为〖讨州〗的目标。②当你使用牌结算结束后,若此牌未造成过伤害,你须弃置一张牌或失去1点体力。",
+ dc_wangling: "新杀谋王淩",
+ dc_wangling_prefix: "新杀谋",
+ dc_simashi: "新杀谋司马师",
+ dc_simashi_prefix: "新杀谋",
+ dc_caoshuang: "新杀谋曹爽",
+ dc_caoshuang_prefix: "新杀谋",
+ dc_jiangji: "新杀谋蒋济",
+ dc_jiangji_prefix: "新杀谋",
+ dc_sb_caoang: "新杀谋曹昂",
+ dc_sb_caoang_prefix: "新杀谋",
+ dcsbfengmin: "丰愍",
+ dcsbfengmin_info: "锁定技,一名角色于其回合内失去装备区的牌后,你摸等同于其装备区空缺装备栏数的牌,然后若你发动〖丰愍〗的次数大于你的体力上限,〖丰愍〗于本回合失效。",
+ dcsbzhiwang: "质死",
+ dcsbzhiwang_info: "每回合限一次,当你因受到牌造成的伤害进入濒死状态时,你可以将此伤害改为无来源并选择一名其他角色,其于本回合结束时可以使用本回合令你进入濒死状态的牌。",
+ dcsbjueying: "绝影",
+ dcsbjueying_info: "当你受到伤害时,你可以弃置装备区里的【绝影】,然后防止此伤害。",
+ dc_sb_guanping: "新杀谋关平",
+ dc_sb_guanping_prefix: "新杀谋",
+ dcsbwuwei: "武威",
+ dcsbwuwei_info: "出牌阶段限一次,你可以将一种颜色的所有手牌当作无距离和次数限制的【杀】使用,然后你选择执行以下X项(X为转化为此【杀】的牌的类别数):①摸一张牌;②令目标角色本回合非锁定技失效;③令本回合〖武威〗可发动次数+1。然后若你执行了所有项,则此【杀】造成的伤害+1。",
+ dc_sb_zhangxiu: "新杀谋张绣",
+ dc_sb_zhangxiu_prefix: "新杀谋",
+ dcsbfuxi: "附袭",
+ dcsbfuxi_info: "其他角色的出牌阶段开始时,若其手牌数为全场最多,则你可以选择一项:①交给其一张牌,然后摸两张牌;②弃置其一张牌,然后视为对其使用一张【杀】。",
+ dcsbhaoyi: "豪意",
+ dcsbhaoyi_info: "结束阶段,你可以获得本回合进入弃牌堆的所有未造成过伤害的伤害牌,然后你可以将这些牌任意分配给其他角色。",
+ zhupeilan: "朱佩兰",
+ dccilv: "辞虑",
+ dccilv_info: "当你成为普通锦囊牌的目标后,你可以摸剩余选项数的牌,然后若你的手牌数大于你的体力上限,则你选择执行并移去一项:①令此牌对你无效;②防止此牌对你造成的伤害;③于此牌结算完毕后获得此牌对应的所有实体牌。",
+ dctongdao: "痛悼",
+ dctongdao_info: "限定技,当你进入濒死状态时,你可以选择一名角色,令其将其拥有的技能重置至游戏开始时的状态,然后若其不为你,则你将体力值回复至与其相同。",
};
export default translates;
diff --git a/character/xianding/voices.js b/character/xianding/voices.js
index 856580cca..77a7331d6 100644
--- a/character/xianding/voices.js
+++ b/character/xianding/voices.js
@@ -65,8 +65,12 @@ export default {
"#dc_sb_zhouyu:die": "人生之艰难,犹如不息之长河……",
"#dcsbmingshi1": "联刘以抗曹,此可行之大势。",
"#dcsbmingshi2": "强敌在北,唯协力可御之。",
- "#dcsbmengmou1": "合左抑右,定两家之盟。",
- "#dcsbmengmou2": "求同存异,邀英雄问鼎。",
+ "#dcsbmingshi_dc_sb_lusu_shadow1": "今天下春秋已定,君不见南北沟壑乎?",
+ "#dcsbmingshi_dc_sb_lusu_shadow2": "善谋者借势而为,其化万物为己用。",
+ "#dcsbmengmou1": "南北同仇,请皇叔移驾江东,共观花火。",
+ "#dcsbmengmou2": "孙刘一家,慕英雄之意,忾窃汉之敌。",
+ "#dcsbmengmou_dc_sb_lusu_shadow1": "合左抑右,定两家之盟。",
+ "#dcsbmengmou_dc_sb_lusu_shadow2": "求同存异,邀英雄问鼎。",
"#dc_sb_lusu:die": "虎可为之用,亦可为之伤……",
"#dcqiongying1": "冰心碎玉壶,光转琼英灿。",
"#dcqiongying2": "玉心玲珑意,撷英倚西楼。",
@@ -434,12 +438,6 @@ export default {
"#wlcuorui1": "减辎疾行,挫敌军锐气。",
"#wlcuorui2": "外物当舍,摄敌为重。",
"#wulan:die": "蛮狗,尔敢杀我!",
- "#wusheng_guansuo1": "逆贼,可识得关氏之勇?",
- "#wusheng_guansuo2": "逆贼,可识得关氏之勇?",
- "#dangxian_guansuo1": "各位将军,且让小辈先行出战!",
- "#dangxian_guansuo2": "各位将军,且让小辈先行出战!",
- "#zhiman_guansuo1": "蛮夷可抚,不可剿!",
- "#zhiman_guansuo2": "蛮夷可抚,不可剿!",
"#tiaoxin_xiahouba1": "跪下受降,饶你不死!",
"#tiaoxin_xiahouba2": "黄口小儿,可听过将军名号?",
"#paoxiao_xiahouba1": "喝啊!",
diff --git a/character/yijiang/characterReplace.js b/character/yijiang/characterReplace.js
index 810c3ec2d..7366501b1 100644
--- a/character/yijiang/characterReplace.js
+++ b/character/yijiang/characterReplace.js
@@ -48,7 +48,7 @@ const characterReplaces = {
gongsunyuan: ["gongsunyuan", "re_gongsunyuan"],
zhoucang: ["zhoucang", "re_zhoucang", "xin_zhoucang"],
guotufengji: ["guotufengji", "re_guotufengji"],
- guanping: ["guanping", "re_guanping"],
+ guanping: ["guanping", "re_guanping", "dc_sb_guanping"],
caifuren: ["caifuren", "re_caifuren", "xin_caifuren"],
guyong: ["guyong", "re_guyong", "xin_guyong", "tw_guyong"],
yj_jushou: ["yj_jushou", "re_jushou", "xin_jushou"],
diff --git a/character/yijiang/skill.js b/character/yijiang/skill.js
index 2068a5d15..7d6da59da 100644
--- a/character/yijiang/skill.js
+++ b/character/yijiang/skill.js
@@ -2894,9 +2894,10 @@ const skills = {
trigger: { player: "phaseBegin" },
forced: true,
audio: "dangxian",
- audioname: ["guansuo", "xin_liaohua", "re_liaohua"],
+ audioname: ["xin_liaohua", "re_liaohua"],
audioname2: {
dc_guansuo: "dangxian_guansuo",
+ guansuo: "dangxian_guansuo",
},
content: function () {
trigger.phaseList.splice(trigger.num, 0, "phaseUse|xindangxian");
@@ -2934,7 +2935,6 @@ const skills = {
},
},
},
- dangxian_guansuo: { audio: 2 },
xinjunxing: {
inherit: "junxing",
audio: "junxing",
@@ -5963,7 +5963,7 @@ const skills = {
trigger.num++;
},
ai: {
- halfneg: true,
+ neg: true,
},
},
huisheng: {
@@ -8140,7 +8140,9 @@ const skills = {
trigger: { player: "phaseBegin" },
forced: true,
audio: 2,
- audioname: ["guansuo"],
+ audioname2: {
+ guansuo: "dangxian_guansuo",
+ },
content: function () {
trigger.phaseList.splice(trigger.num, 0, "phaseUse|dangxian");
},
@@ -8774,7 +8776,7 @@ const skills = {
if (player.hp != 1) return false;
},
respondSha: true,
- halfneg: true,
+ neg: true,
},
audio: 2,
audioname: ["xin_zhangyi"],
@@ -10221,6 +10223,8 @@ const skills = {
},
},
fuhun3: {},
+ wusheng_guanzhang: { audio: 1 },
+ paoxiao_guanzhang: { audio: 1 },
fencheng: {
skillAnimation: "epic",
animationColor: "gray",
@@ -10630,7 +10634,9 @@ const skills = {
},
zhiman: {
audio: 2,
- audioname: ["guansuo"],
+ audioname2: {
+ guansuo: "zhiman_guansuo",
+ },
trigger: { source: "damageBegin2" },
check: function (event, player) {
if (get.damageEffect(event.player, player, player) < 0) return true;
@@ -10782,9 +10788,10 @@ const skills = {
olsanyao1: {},
rezhiman: {
audio: "zhiman",
- audioname: ["guansuo", "re_masu"],
+ audioname: ["re_masu"],
audioname2: {
dc_guansuo: "zhiman_guansuo",
+ guansuo: "zhiman_guansuo",
},
trigger: { source: "damageBegin2" },
filter: function (event, player) {
@@ -10812,7 +10819,6 @@ const skills = {
trigger.cancel();
},
},
- zhiman_guansuo: { audio: 2 },
resanyao: {
audio: 2,
enable: "phaseUse",
@@ -14377,7 +14383,7 @@ const skills = {
threaten: 0.9,
effect: {
target: function (card, player, target) {
- if (player.hasSkillTag("jueqing")) return;
+ if (player.hasSkillTag("jueqing", false, target)) return;
if (target.hujia) return;
if (player._shibei_tmp) return;
if (target.hasSkill("shibei_ai")) return;
diff --git a/character/yijiang/voices.js b/character/yijiang/voices.js
index bd40ae7e7..90ad83f06 100644
--- a/character/yijiang/voices.js
+++ b/character/yijiang/voices.js
@@ -50,7 +50,7 @@ export default {
"#xin_fazheng:die": "汉室复兴,我,是看不到了……",
"#fuhun1": "光复汉室,重任在肩!",
"#fuhun2": "将门虎子,承我父志!",
- "#guanzhang:die": "未能手刃仇敌,愧对先父。",
+ "#guanzhang:die": "未能手刃仇敌,愧对先父……",
"#zhenlie1": "虽是妇人,亦当奋身一搏!",
"#zhenlie2": "为雪前耻,不惜吾身!",
"#miji1": "此计,可歼敌精锐!",
@@ -91,12 +91,13 @@ export default {
"#sanyao2": "散谣惑敌,不攻自破!",
"#zhiman1": "丞相多虑,且看我的!",
"#zhiman2": "兵法谙熟于心,取胜千里之外!",
+ "#xin_masu:die": "败军之罪,万死难赎!",
"#danshou1": "以胆为守,扼敌咽喉!",
"#danshou2": "到此为止了!",
"#zhuran:die": "何人竟有如此之胆!?",
"#xinpojun1": "大军在此!汝等休想前进一步!",
"#xinpojun2": "敬请,养精蓄锐!",
- "#xusheng:die": "可怜一身胆略,尽随一抔黄土……",
+ "#xusheng:die": "盛不能奋身出命,不亦辱乎……",
"#ganlu1": "男婚女嫁,须当交换文定之物。",
"#ganlu2": "此真乃吾之佳婿也。",
"#buyi1": "吾乃吴国之母,何人敢放肆?",
@@ -364,15 +365,14 @@ export default {
"#xuezong:die": "尔等,竟做如此有辱斯文之事……",
"#shiyong1": "好大一股杀气啊!",
"#shiyong2": "好大一股酒气啊!",
+ "#old_huaxiong:die": "皮厚,不挡刀啊……",
"#jieyue1": "安营驻寨,严守城防。",
"#jieyue2": "诸军严整,敌军自乱。",
"#yujin:die": "我,无颜面对丞相了……",
"#reqiaoshui1": "慧心妙舌,难题可解。",
"#reqiaoshui2": "巧言善辩,应对自如。",
"#wusheng_guanzhang1": "一夫当关,万夫莫当!",
- "#wusheng_guanzhang2": "一夫当关,万夫莫当!",
"#paoxiao_guanzhang1": "喝啊~",
- "#paoxiao_guanzhang2": "喝啊~",
"#luoying_discard1": "别着急扔,给我就好。",
"#luoying_discard2": "这些都是我的。",
"#luoying_judge1": "别着急扔,给我就好。",
diff --git a/character/yingbian/skill.js b/character/yingbian/skill.js
index 32dc72cb0..25019f6ca 100644
--- a/character/yingbian/skill.js
+++ b/character/yingbian/skill.js
@@ -1750,7 +1750,7 @@ const skills = {
var skill = lib.skill[j];
if (!skill || skill.juexingji || skill.hiddenSkill || skill.zhuSkill || skill.dutySkill || skill.chargeSkill || lib.skill.bolan.banned.includes(j)) continue;
if (skill.init || (skill.ai && (skill.ai.combo || skill.ai.notemp || skill.ai.neg))) continue;
- var info = lib.translate[j + "_info"];
+ var info = get.plainText(lib.translate[j + "_info"]);
if (info && info.indexOf("出牌阶段限一次") != -1) skills.add(j);
}
}
@@ -2313,6 +2313,9 @@ const skills = {
if (player.getEquips(5).length) return distance - 1;
},
},
+ ai: {
+ combo: "chexuan"
+ },
},
cheliji_sichengliangyu: {
trigger: { global: "phaseJieshuBegin" },
diff --git a/game/asset.js b/game/asset.js
index d118d75a4..3bb0812a9 100644
--- a/game/asset.js
+++ b/game/asset.js
@@ -636,7 +636,9 @@ window.noname_asset_list = [
"audio/die/ol_liushan.mp3",
"audio/die/ol_lukai.mp3",
"audio/die/ol_lusu.mp3",
- "audio/die/ol_masu.mp3",
+ "audio/die/xin_masu.mp3",
+ "audio/die/old_zhoutai.mp3",
+ "audio/die/old_huaxiong.mp3",
"audio/die/ol_mengda.mp3",
"audio/die/ol_pangde.mp3",
"audio/die/ol_pangtong.mp3",
diff --git a/image/character/caimao.jpg b/image/character/caimao.jpg
new file mode 100644
index 000000000..7d53ea667
Binary files /dev/null and b/image/character/caimao.jpg differ
diff --git a/image/character/chezhou.jpg b/image/character/chezhou.jpg
new file mode 100644
index 000000000..545d74e36
Binary files /dev/null and b/image/character/chezhou.jpg differ
diff --git a/image/character/clan_wuqiao.jpg b/image/character/clan_wuqiao.jpg
index 2ca0a9816..54c2a5dbf 100644
Binary files a/image/character/clan_wuqiao.jpg and b/image/character/clan_wuqiao.jpg differ
diff --git a/image/character/dc_sb_lusu_shadow.jpg b/image/character/dc_sb_lusu_shadow.jpg
new file mode 100644
index 000000000..48f3a1e93
Binary files /dev/null and b/image/character/dc_sb_lusu_shadow.jpg differ
diff --git a/image/character/hansong.jpg b/image/character/hansong.jpg
new file mode 100644
index 000000000..72ed164c0
Binary files /dev/null and b/image/character/hansong.jpg differ
diff --git a/image/character/matie.jpg b/image/character/matie.jpg
new file mode 100644
index 000000000..3adbd320a
Binary files /dev/null and b/image/character/matie.jpg differ
diff --git a/image/character/ol_jiangwan.jpg b/image/character/ol_jiangwan.jpg
new file mode 100644
index 000000000..f39147c10
Binary files /dev/null and b/image/character/ol_jiangwan.jpg differ
diff --git a/image/character/ol_liupi.jpg b/image/character/ol_liupi.jpg
index c63d20821..138bf5693 100644
Binary files a/image/character/ol_liupi.jpg and b/image/character/ol_liupi.jpg differ
diff --git a/image/character/ol_liwan.jpg b/image/character/ol_liwan.jpg
index 6727be3e5..fc32f67c7 100644
Binary files a/image/character/ol_liwan.jpg and b/image/character/ol_liwan.jpg differ
diff --git a/image/character/ol_peixiu.jpg b/image/character/ol_peixiu.jpg
new file mode 100644
index 000000000..87aca4574
Binary files /dev/null and b/image/character/ol_peixiu.jpg differ
diff --git a/image/character/std_mateng.jpg b/image/character/std_mateng.jpg
index 206b5c8e1..2591dfc9e 100644
Binary files a/image/character/std_mateng.jpg and b/image/character/std_mateng.jpg differ
diff --git a/image/character/xin_sunquan.jpg b/image/character/xin_sunquan.jpg
new file mode 100644
index 000000000..8c86a38ff
Binary files /dev/null and b/image/character/xin_sunquan.jpg differ
diff --git a/image/character/yj_ehuan.jpg b/image/character/yj_ehuan.jpg
new file mode 100644
index 000000000..0a55fd364
Binary files /dev/null and b/image/character/yj_ehuan.jpg differ
diff --git a/image/character/yue_miheng.jpg b/image/character/yue_miheng.jpg
new file mode 100644
index 000000000..1607ed9f6
Binary files /dev/null and b/image/character/yue_miheng.jpg differ
diff --git a/mode/boss.js b/mode/boss.js
index d971b6481..bb352bf43 100644
--- a/mode/boss.js
+++ b/mode/boss.js
@@ -1327,7 +1327,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
boss_zhugeliang: [
"male",
"shen",
- Infinity,
+ "Infinity/Infinity",
["xiangxing", "yueyin", "fengqi", "gaiming"],
["shu", "boss", "bossallowed"],
"qun",
@@ -1406,7 +1406,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"shen",
"1/8",
["boss_jiang", "boss_hunzi", "boss_hunyou", "boss_taoni"],
- ["qun", "boss", "bossallowed", "InitFilter:noZhuHp:noZhuSkill"],
+ ["qun", "boss", "bossallowed", "InitFilter:noZhuHp:noZhuSkill", "die:sunce"],
"wu",
],
@@ -7158,7 +7158,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
content: function (storage, player) {
var str = "扣减" + (7 - player.storage.xiangxing_count) + "点体力后失去下一枚星;";
str +=
- "防上禳星伤害条件:" +
+ "防止禳星伤害条件:" +
lib.translate["xiangxing" + player.storage.xiangxing + "_info"];
return str;
},
@@ -7171,10 +7171,10 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
return player.countCards("h") == 0;
},
x6: function (player, event) {
- return event.hasNature("fire");
+ if(event.hasNature) return event.hasNature("fire");
},
x5: function (player, event) {
- return event.hasNature("thunder");
+ if(event.hasNature) return event.hasNature("thunder");
},
x4: function (player, event) {
return event.name == "loseHp";
@@ -9641,6 +9641,8 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
},
+ reyingzi_sunce: { audio: 2 },
+ yinghun_sunce: { audio: 2 },
boss_jiang: {
audio: "jiang",
trigger: {
@@ -9691,6 +9693,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
group: ["boss_jiang_use"],
subSkill: {
use: {
+ audio: "jiang",
trigger: {
global: ["useCard"],
},
@@ -10505,7 +10508,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"觉醒技,准备阶段,若你的体力值为1,你减1点体力上限,失去技能〖魂佑〗并获得技能〖英姿〗和〖英魂〗。",
boss_jiang: "激昂",
boss_jiang_info:
- "①锁定技,〖激昂〗不会无效。
②每当你使用或打出红色牌时,你可以摸一张牌。若你是因响应其他角色使用或打出的牌,则你获得对方使用或打出的牌。
③当有其他角色使用或打出红色牌指定你为目标或响应你后,你可以摸一张牌并获得这些牌。",
+ "①锁定技,〖激昂〗不会无效。②每当你使用或打出红色牌时,你可以摸一张牌。若你是因响应其他角色使用或打出的牌,则你获得对方使用或打出的牌。③当有其他角色使用或打出红色牌指定你为目标或响应你后,你可以摸一张牌并获得这些牌。",
boss_hunyou: "魂佑",
boss_hunyou_info: "锁定技,你的体力值变化和体力上限变化无效。",
boss_taoni: "讨逆",
@@ -10558,6 +10561,29 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
mode_boss_card_config: "挑战卡牌",
mode_boss_character_config: "挑战武将",
+
+ // 台词部分
+ "#boss_lvbu1:die": "虎牢关,失守了……",
+ "#xiuluo1": "准备受死吧!",
+ "#xiuluo2": "鼠辈!螳臂当车!",
+ "#shenwei1": "萤烛之火,也敢与日月争辉?",
+ "#shenwei2": "我不会输给任何人!",
+ "#shenji1": "杂鱼们!都去死吧!",
+ "#shenji2": "竟想赢我?痴人说梦!",
+ "#boss_lvbu2:die": "虎牢关,失守了……",
+ "#shenqu1": "别心怀侥幸了,你们不可能赢!",
+ "#shenqu2": "虎牢关,我一人镇守足矣!",
+ "#jiwu1": "我,是不可战胜的!",
+ "#jiwu2": "今天,就让你们感受一下真正的绝望!",
+ "#qiangxi_boss_lvbu31": "这么想死,那我就成全你!",
+ "#qiangxi_boss_lvbu32": "项上人头,待我来取!",
+ "#retieji_boss_lvbu31": "哈哈哈,破绽百出!",
+ "#retieji_boss_lvbu32": "我要让这虎牢关下,血流成河!",
+ "#xuanfeng_boss_lvbu31": "千钧之势,力贯苍穹!",
+ "#xuanfeng_boss_lvbu32": "横扫六合,威震八荒!",
+ "#wansha_boss_lvbu31": "蝼蚁,怎容偷生?",
+ "#wansha_boss_lvbu32": "沉沦吧,在这无边的恐惧!",
+ "#boss_lvbu3:die": "你们的项上人头,我改日再取!",
},
get: {
rawAttitude: function (from, to) {
diff --git a/mode/guozhan.js b/mode/guozhan.js
index 0dabca389..479eae002 100644
--- a/mode/guozhan.js
+++ b/mode/guozhan.js
@@ -826,9 +826,9 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
gz_sp_dongzhuo: ["male", "qun", 4, ["hengzheng", "fakebaoling"]],
gz_zhangren: ["male", "qun", 4, ["chuanxin", "fengshi"]],
- gz_jun_liubei: ["male", "shu", 4, ["zhangwu", "jizhao", "shouyue", "wuhujiangdaqi"]],
- gz_jun_zhangjiao: ["male", "qun", 4, ["wuxin", "hongfa", "wendao", "huangjintianbingfu"]],
- gz_jun_sunquan: ["male", "wu", 4, ["jiahe", "lianzi", "jubao", "yuanjiangfenghuotu"]],
+ gz_jun_liubei: ["male", "shu", 4, ["zhangwu", "jizhao", "shouyue"]],
+ gz_jun_zhangjiao: ["male", "qun", 4, ["wuxin", "hongfa", "wendao"]],
+ gz_jun_sunquan: ["male", "wu", 4, ["jiahe", "lianzi", "jubao"]],
gz_liqueguosi: ["male", "qun", 4, ["gzxiongsuan"]],
gz_zuoci: ["male", "qun", 3, ["fakeyigui", "fakejihun"], ["gzskin"]],
@@ -859,12 +859,12 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
gz_cuimao: ["male", "wei", 3, ["gzzhengbi", "gzfengying"], []],
gz_yujin: ["male", "wei", 4, ["gzjieyue"], ["gzskin"]],
gz_wangping: ["male", "shu", 4, ["jianglue"], ["gzskin"]],
- gz_fazheng: ["male", "shu", 3, ["gzxuanhuo", "gzenyuan"], ["gzskin"]],
+ gz_fazheng: ["male", "shu", 3, ["gzxuanhuo", "gzenyuan"], ["gzskin", "die:xin_fazheng"]],
gz_wuguotai: ["female", "wu", 3, ["gzbuyi", "ganlu"], ["gzskin"]],
gz_lukang: ["male", "wu", 4, ["fakejueyan", "fakekeshou"], ["gzskin"]],
gz_yuanshu: ["male", "qun", 4, ["gzweidi", "gzyongsi"], ["gzskin"]],
gz_zhangxiu: ["male", "qun", 4, ["gzfudi", "gzcongjian"], ["gzskin"]],
- gz_jun_caocao: ["male", "wei", 4, ["jianan", "huibian", "gzzongyu", "wuziliangjiangdao"], []],
+ gz_jun_caocao: ["male", "wei", 4, ["jianan", "huibian", "gzzongyu"], []],
gz_jin_zhangchunhua: ["female", "jin", 3, ["gzhuishi", "fakeqingleng"]],
gz_jin_simayi: ["male", "jin", 3, ["fakequanbian", "smyyingshi", "fakezhouting"]],
@@ -925,6 +925,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
//官盗2023
fakexiaoguo: {
audio: "xiaoguo",
+ audioname2: { gz_jun_caocao: "jianan_xiaoguo" },
trigger: { global: "phaseZhunbeiBegin" },
filter(event, player) {
return (
@@ -6719,7 +6720,9 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
mod: {
maxHandcard: function (player, num) {
if (!player.hasEmptySlot(2)) return;
- if (player.hasSkill("huangjintianbingfu")) {
+ // if (player.hasSkill("hongfa")) {
+ // 村规
+ if (player.hasSkill("hongfa", null, null, false)) {
num += player.getExpansions("huangjintianbingfu").length;
}
return (
@@ -8168,7 +8171,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
event.target = target;
player.awakenSkill("gzshigong");
var list = lib.character[player.name2][3].filter(function (skill) {
- return get.skillCategoriesOf(skill).length == 0;
+ return get.skillCategoriesOf(skill, player).length == 0;
});
if (!list.length) {
event._result = { control: "cancel2" };
@@ -9819,6 +9822,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
//黄忠
gzliegong: {
audio: "liegong",
+ audioname2: { gz_jun_liubei: "shouyue_liegong" },
locked: false,
mod: {
targetInRange: function (card, player, target) {
@@ -9937,7 +9941,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
gzwushuang: {
shaRelated: true,
audio: "wushuang",
- audioname: ["re_lvbu", "shen_lvbu", "lvlingqi"],
+ audioname2: { gz_lvlingqi: "wushuang_lvlingqi" },
forced: true,
locked: true,
group: ["wushuang1", "wushuang2"],
@@ -10080,6 +10084,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
derivation: "gzwushuang",
},
+ wushuang_lvlingqi: { audio: 2 },
//荀谌
gzfenglve: {
audio: "refenglve",
@@ -15639,19 +15644,21 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
jianan: {
- audio: 2,
+ audio: true,
unique: true,
forceunique: true,
- group: "wuziliangjiangdao",
- derivation: "wuziliangjiangdao",
+ derivation: ["wuziliangjiangdao", "new_retuxi", "qiaobian", "fakexiaoguo", "gzjieyue", "new_duanliang"],
lordSkill: true,
- global: "g_jianan",
+ global: ["wuziliangjiangdao", "g_jianan"],
+ init(player) {
+ player.markSkill("wuziliangjiangdao");
+ },
},
g_jianan: {
trigger: {
player: ["phaseZhunbeiBegin", "phaseBefore", "dieBegin"],
},
- audio: "jianan",
+ audio: "wuziliangjiangdao",
forceaudio: true,
filter: function (event, player, name) {
if (name != "phaseZhunbeiBegin") return get.is.jun(player) && player.identity == "wei";
@@ -15774,11 +15781,32 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
player.addTempSkill(link, "jiananUpdate");
player.addTempSkill("jianan_eff", "jiananUpdate");
game.log(player, "获得了技能", "#g【" + get.translation(result.control) + "】");
+
+ // 语音修复
+ var map = {
+ new_retuxi: "jianan_tuxi",
+ qiaobian: "jianan_qiaobian",
+ fakexiaoguo: "jianan_xiaoguo",
+ gzjieyue: "jianan_jieyue",
+ new_duanliang: "jianan_duanliang"
+ };
+ var mapSkills = map[link];
+ game.broadcastAll(function () {
+ var info = lib.skill[link];
+ if (!info.audioname2) info.audioname2 = {};
+ info.audioname2[player.name1] = mapSkills;
+ info.audioname2[player.name2] = mapSkills;
+ }, link);
},
},
jianan_eff: {
ai: { nomingzhi: true },
},
+ jianan_tuxi: { audio: true },
+ jianan_qiaobian: { audio: true },
+ jianan_xiaoguo: { audio: true },
+ jianan_jieyue: { audio: true },
+ jianan_duanliang: { audio: true },
huibian: {
enable: "phaseUse",
audio: 2,
@@ -15823,9 +15851,11 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
gzzongyu: {
audio: 2,
+ derivation: "liulongcanjia",
unique: true,
forceunique: true,
- group: ["gzzongyu_others", "gzzongyu_player"],
+ group: "gzzongyu_others",
+ global: "gzzongyu_player",
ai: {
threaten: 1.2,
},
@@ -15873,9 +15903,13 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
player: {
audio: "gzzongyu",
+ forceaudio: true,
trigger: { player: "equipAfter" },
forced: true,
filter: function (event, player) {
+ // if (!player.hasSkill("gzzongyu")) return false;
+ // 村规
+ if (!player.hasSkill("gzzongyu", null, null, false)) return false;
if (!["equip3", "equip4"].includes(get.subtype(event.card))) return false;
for (var i = 0; i < ui.discardPile.childElementCount; i++) {
if (ui.discardPile.childNodes[i].name == "liulongcanjia") return true;
@@ -15913,6 +15947,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
wuziliangjiangdao: {
+ audio: 2,
nopop: true,
unique: true,
forceunique: true,
@@ -16317,6 +16352,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
audio: ["jieyue", 2],
+ audioname2: { gz_jun_caocao: "jianan_jieyue" },
},
jianglue: {
@@ -16466,11 +16502,11 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
gzxuanhuo: {
- audio: "rexuanhuo",
+ audio: "xinxuanhuo",
global: "gzxuanhuo_others",
derivation: [
- "fz_new_rewusheng",
- "fz_gzpaoxiao",
+ "fz_wusheng",
+ "fz_new_paoxiao",
"fz_new_longdan",
"fz_new_tieji",
"fz_liegong",
@@ -16489,7 +16525,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
subSkill: {
others: {
- audio: "rexuanhuo",
+ audio: "xinxuanhuo",
forceaudio: true,
enable: "phaseUse",
usable: 1,
@@ -16540,7 +16576,15 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
.set("prompt", "选择并获得一项技能直到回合结束");
"step 1";
player.popup(result.control);
- player.addTempSkill("fz_" + result.control);
+ var map = {
+ new_rewusheng: "fz_wusheng",
+ gzpaoxiao: "fz_new_paoxiao",
+ new_longdan: "fz_new_longdan",
+ new_tieji: "fz_new_tieji",
+ liegong: "fz_liegong",
+ xinkuanggu: "fz_xinkuanggu"
+ };
+ player.addTempSkill(map[result.control]);
game.log(player, "获得了技能", "#g【" + get.translation(result.control) + "】");
game.delay();
},
@@ -16555,7 +16599,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
// audio:['xuanhuo',2],
},
- fz_gzpaoxiao: {
+ fz_new_paoxiao: {
audio: true,
inherit: "gzpaoxiao",
},
@@ -16563,7 +16607,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
audio: true,
inherit: "new_tieji",
},
- fz_new_rewusheng: {
+ fz_wusheng: {
audio: true,
inherit: "new_rewusheng",
},
@@ -16736,7 +16780,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
gzenyuan: {
locked: true,
- audio: "reenyuan",
+ audio: "xinenyuan",
group: ["gzenyuan_gain", "gzenyuan_damage"],
preHidden: true,
ai: {
@@ -16751,7 +16795,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
subSkill: {
gain: {
- audio: "reenyuan",
+ audio: "xinenyuan",
trigger: { target: "useCardToTargeted" },
forced: true,
filter: function (event, player) {
@@ -16763,7 +16807,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
damage: {
- audio: "reenyuan",
+ audio: "xinenyuan",
trigger: { player: "damageEnd" },
forced: true,
filter: function (event, player) {
@@ -16857,6 +16901,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
locked: false,
audio: "duanliang1",
+ audioname2: { gz_jun_caocao: "jianan_duanliang" },
enable: "chooseToUse",
filterCard: function (card) {
if (get.type(card) != "basic" && get.type(card) != "equip") return false;
@@ -17278,6 +17323,8 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
new_longdan: {
+ audio: "longdan_sha",
+ audioname2: { gz_jun_liubei: "shouyue_longdan" },
group: [
"new_longdan_sha",
"new_longdan_shan",
@@ -17289,6 +17336,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
shanafter: {
sub: true,
audio: "longdan_sha",
+ audioname2: { gz_jun_liubei: "shouyue_longdan" },
trigger: {
player: "useCard",
},
@@ -17324,6 +17372,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
shamiss: {
sub: true,
audio: "longdan_sha",
+ audioname2: { gz_jun_liubei: "shouyue_longdan" },
trigger: {
player: "shaMiss",
},
@@ -17356,6 +17405,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
player: ["useCard", "respond"],
},
audio: "longdan_sha",
+ audioname2: { gz_jun_liubei: "shouyue_longdan" },
forced: true,
locked: false,
filter: function (event, player) {
@@ -17370,6 +17420,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
sha: {
audio: "longdan_sha",
+ audioname2: { gz_jun_liubei: "shouyue_longdan" },
enable: ["chooseToUse", "chooseToRespond"],
filterCard: {
name: "shan",
@@ -17403,6 +17454,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
shan: {
audio: "longdan_sha",
+ audioname2: { gz_jun_liubei: "shouyue_longdan" },
enable: ["chooseToRespond", "chooseToUse"],
filterCard: {
name: "sha",
@@ -17435,6 +17487,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
gzpaoxiao: {
audio: "paoxiao",
+ audioname2: { gz_jun_liubei: "shouyue_paoxiao" },
trigger: {
player: "useCard",
},
@@ -17940,6 +17993,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
new_tieji: {
audio: "retieji",
+ audioname2: { gz_jun_liubei: "shouyue_tieji" },
trigger: {
player: "useCardToPlayered",
},
@@ -18828,6 +18882,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
enable: "phaseUse",
usable: 1,
audio: 2,
+ derivation: "gzzhiheng",
filterCard: true,
check: function (card) {
if (get.type(card) == "equip") return 0;
@@ -18899,6 +18954,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
trigger: { player: "phaseJieshuBegin" },
audio: 2,
+ derivation: "dinglanyemingzhu",
forced: true,
unique: true,
filter: function (event, player) {
@@ -18935,14 +18991,20 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
jiahe: {
+ audio: true,
unique: true,
forceunique: true,
lordSkill: true,
- locked: false,
- audio: 2,
- derivation: "yuanjiangfenghuotu",
mark: true,
- global: ["jiahe_put", "jiahe_skill"],
+ derivation: ["yuanjiangfenghuotu", "jiahe_reyingzi", "jiahe_haoshi", "jiahe_shelie", "jiahe_duoshi"],
+ global: ["yuanjiangfenghuotu", "jiahe_damage", "jiahe_put", "jiahe_skill"],
+ init(player) {
+ player.markSkill("yuanjiangfenghuotu");
+ },
+ },
+ jiahe_damage: {
+ audio: ["yuanjiangfenghuotu3.mp3", "yuanjiangfenghuotu4.mp3"],
+ forceaudio: true,
ai: {
threaten: 2,
},
@@ -18971,7 +19033,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
jiahe_put: {
enable: "phaseUse",
- audio: 2,
+ audio: ["yuanjiangfenghuotu", 2],
forceaudio: true,
filter: function (event, player) {
var zhu = get.zhu(player, "jiahe");
@@ -19064,10 +19126,10 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
event.num = zhu.getExpansions("yuanjiangfenghuotu").length;
"step 1";
var list = [];
- if (event.num >= 1 && !player.hasSkill("jiahe_reyingzi")) list.push("reyingzi");
- if (event.num >= 2 && !player.hasSkill("jiahe_haoshi")) list.push("haoshi");
- if (event.num >= 3 && !player.hasSkill("jiahe_shelie")) list.push("shelie");
- if (event.num >= 4 && !player.hasSkill("jiahe_duoshi")) list.push("fakeduoshi");
+ if (event.num >= 1 && !(player.hasSkill("reyingzi") || player.hasSkill("jiahe_reyingzi"))) list.push("reyingzi");
+ if (event.num >= 2 && !(player.hasSkill("haoshi") || player.hasSkill("jiahe_haoshi"))) list.push("haoshi");
+ if (event.num >= 3 && !(player.hasSkill("shelie") || player.hasSkill("jiahe_shelie"))) list.push("shelie");
+ if (event.num >= 4 && !player.hasSkill("fakeduoshi")) list.push("fakeduoshi");
if (!list.length) {
event.finish();
return;
@@ -19109,8 +19171,30 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
});
"step 2";
if (result.control != "cancel2") {
- var skill = (result.control != "fakeduoshi" ? "jiahe_" : "") + result.control;
- player.addTempSkills(skill);
+ var map = {
+ reyingzi: "jiahe_reyingzi",
+ haoshi: "jiahe_haoshi",
+ shelie: "jiahe_shelie",
+ fakeduoshi: "fakeduoshi"
+ };
+ var skills = map[result.control];
+ player.addTempSkills(skills);
+
+ // 语音修复
+ if (skills == "fakeduoshi") {
+ var mapSkills = "jiahe_duoshi";
+ game.broadcastAll(function () {
+ var info = lib.skill[skills];
+ if (!info.audioname2) info.audioname2 = {};
+ info.audioname2[player.name1] = mapSkills;
+ info.audioname2[player.name2] = mapSkills;
+ var subSkillInfo = info.subSkill.global;
+ if (!subSkillInfo.audioname2) subSkillInfo.audioname2 = {};
+ subSkillInfo.audioname2[player.name1] = mapSkills;
+ subSkillInfo.audioname2[player.name2] = mapSkills;
+ }, skills);
+ }
+
if (!event.done) player.logSkill("jiahe_put");
// game.log(player,'获得了技能','【'+get.translation(skill)+'】');
if (event.num >= 5 && !event.done) {
@@ -19121,18 +19205,23 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
jiahe_reyingzi: {
+ audio: 2,
inherit: "reyingzi",
},
jiahe_haoshi: {
+ audio: 2,
inherit: "haoshi",
},
jiahe_shelie: {
+ audio: 2,
inherit: "shelie",
},
jiahe_duoshi: {
- inherit: "duoshi",
+ audio: 2,
+ inherit: "fakeduoshi",
},
yuanjiangfenghuotu: {
+ audio: 4,
unique: true,
forceunique: true,
nopop: true,
@@ -19150,7 +19239,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
dialog.addSmall(content);
}
dialog.addText(
- '- 每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。
- 根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张以上~英姿;两张以上~好施;三张以上~涉猎;四张以上~度势;五张以上~可额外选择一项。
- 锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。',
+ '
- 每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。
- 根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张及以上~英姿;两张及以上~好施;三张及以上~涉猎;四张及以上~度势;五张及以上~可额外选择一项。
- 锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。',
false
);
},
@@ -19159,7 +19248,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
gzqice: {
enable: "phaseUse",
usable: 1,
- audio: "qice_backup",
+ audio: "qice",
filter: function (event, player) {
var hs = player.getCards("h");
if (!hs.length) return false;
@@ -19243,7 +19332,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
backup: function (links, player) {
return {
filterCard: true,
- audio: "qice_backup",
+ audio: "qice",
selectCard: -1,
position: "h",
selectTarget: function () {
@@ -19785,7 +19874,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
hongfa_respond: {
- audio: "huangjintianbingfu",
+ audio: ["huangjintianbingfu", 2],
forceaudio: true,
trigger: { player: "chooseToRespondBegin" },
direct: true,
@@ -19823,7 +19912,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
hongfa_use: {
- audio: "huangjintianbingfu",
+ audio: ["huangjintianbingfu", 2],
forceaudio: true,
enable: "chooseToUse",
filter: function (event, player) {
@@ -19883,13 +19972,17 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
hongfa: {
- audio: 2,
+ audio: 3,
+ locked: false,
derivation: "huangjintianbingfu",
unique: true,
forceunique: true,
lordSkill: true,
trigger: { player: "phaseZhunbeiBegin" },
forced: true,
+ init(player) {
+ player.markSkill("huangjintianbingfu");
+ },
filter: function (event, player) {
return (
player.getExpansions("huangjintianbingfu").length == 0 && get.population("qun") > 0
@@ -19903,10 +19996,10 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
threaten: 2,
},
group: "hongfa_hp",
- global: ["hongfa_use", "hongfa_respond"],
+ global: ["huangjintianbingfu", "hongfa_use", "hongfa_respond"],
subSkill: {
hp: {
- audio: true,
+ audio: "huangjintianbingfu3.mp3",
trigger: { player: "loseHpBefore" },
filter: function (event, player) {
return player.getExpansions("huangjintianbingfu").length > 0;
@@ -19924,7 +20017,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
});
"step 1";
if (result.bool) {
- player.logSkill("huangjintianbingfu");
+ player.logSkill("hongfa_hp");
player.loseToDiscardpile(result.links);
trigger.cancel();
}
@@ -19934,6 +20027,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
wendao: {
audio: 2,
+ derivation: "taipingyaoshu",
unique: true,
forceunique: true,
enable: "phaseUse",
@@ -19994,7 +20088,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
huangjintianbingfu: {
- audio: 2,
+ audio: 3,
unique: true,
forceunique: true,
nopop: true,
@@ -20012,7 +20106,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
dialog.addSmall(content);
}
dialog.addText(
- '
- 当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
- 每当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
- 与你势力相同的角色可将一张“天兵”当【杀】使用或打出。',
+ '
- 锁定技,当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
- 每当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
- 与你势力相同的角色可将一张“天兵”当【杀】使用或打出。',
false
);
},
@@ -20027,7 +20121,9 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
content: function () {
"step 0";
var num = get.population("qun");
- if (player.hasSkill("huangjintianbingfu")) {
+ // if (player.hasSkill("hongfa")) {
+ // 村规
+ if (player.hasSkill("hongfa", null, null, false)) {
num += player.getExpansions("huangjintianbingfu").length;
}
var cards = get.cards(num);
@@ -20053,6 +20149,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
zhangwu: {
audio: 2,
+ derivation: "feilongduofeng",
unique: true,
forceunique: true,
ai: {
@@ -20175,13 +20272,22 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
},
shouyue: {
+ audio: true,
unique: true,
forceunique: true,
- group: "wuhujiangdaqi",
- derivation: "wuhujiangdaqi",
+ global: "wuhujiangdaqi",
+ derivation: ["wuhujiangdaqi", "new_rewusheng", "gzpaoxiao", "new_longdan", "new_tieji", "gzliegong"],
mark: true,
lordSkill: true,
+ init(player) {
+ player.markSkill("wuhujiangdaqi");
+ },
},
+ shouyue_wusheng: { audio: 2 },
+ shouyue_paoxiao: { audio: 2 },
+ shouyue_longdan: { audio: 2 },
+ shouyue_tieji: { audio: 2 },
+ shouyue_liegong: { audio: 2 },
wuhujiangdaqi: {
unique: true,
forceunique: true,
@@ -20189,7 +20295,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
mark: true,
intro: {
content:
- '@
【武圣】
将“红色牌”改为“任意牌”
【咆哮】
增加描述“你使用的【杀】无视其他角色的防具”
【龙胆】
增加描述“你每发动一次‘龙胆’便摸一张牌”
【烈弓】
增加描述“你的攻击范围+1”
【铁骑】
将“一张明置的武将牌”改为“所有明置的武将牌”
',
+ '@【武圣】
将“红色牌”改为“任意牌”
【咆哮】
增加描述“你使用的【杀】无视其他角色的防具”
【龙胆】
增加描述“你每发动一次‘龙胆’便摸一张牌”
【铁骑】
将“一张明置的武将牌”改为“所有明置的武将牌”
【烈弓】
增加描述“你的攻击范围+1”
',
},
},
jizhao: {
@@ -21342,7 +21448,17 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
var to = event.junzhu_name;
event.maxHp = player.maxHp;
player.reinit(player.name1, to, 4);
- if (lib.skill[to]) game.trySkillAudio(to, player);
+
+ // 修改君主亮将配音播放
+ // if (lib.skill[to]) game.trySkillAudio(to, player);
+ var map = {
+ gz_jun_liubei: "shouyue",
+ gz_jun_zhangjiao: "hongfa",
+ gz_jun_sunquan: "jiahe",
+ gz_jun_caocao: "jianan"
+ };
+ game.trySkillAudio(map[to],player);
+
player.showCharacter(0);
var group = lib.character[to][1];
var yelist = game.filterPlayer(function (current) {
@@ -21562,10 +21678,10 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
}
},
},
- gz_jun_liubei: { audio: true },
- gz_jun_caocao: { audio: true },
- gz_jun_sunquan: { audio: true },
- gz_jun_zhangjiao: { audio: true },
+ // gz_jun_liubei: { audio: true },
+ // gz_jun_caocao: { audio: true },
+ // gz_jun_sunquan: { audio: true },
+ // gz_jun_zhangjiao: { audio: true },
_zhenfazhaohuan: {
enable: "phaseUse",
usable: 1,
@@ -23290,7 +23406,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
gz_jun_caocao: "君曹操",
gz_jun_caocao_prefix: "君",
jianan: "建安",
- jianan_info: "君主技,只要此武将处于明置状态,你便拥有“五子良将纛”。",
+ jianan_info: "君主技,只要此武将牌处于明置状态,你便拥有“五子良将纛”。",
g_jianan: "五子良将纛",
wuziliangjiangdao: "五子良将纛",
wuziliangjiangdao_ab: "将纛",
@@ -23457,12 +23573,13 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"锁定技,你装备区里的宝物牌不能被其他角色获得。结束阶段,若场上或弃牌堆有【定澜夜明珠】,则你摸一张牌,然后获得装备区里有【定澜夜明珠】角色的一张牌。",
jiahe: "嘉禾",
jiahe_info: "君主技,只要此武将牌处于明置状态,你便拥有“缘江烽火图”。",
+ jiahe_damage: "缘江烽火图",
jiahe_put: "烽火",
jiahe_put_info: "出牌阶段限一次,你可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。",
jiahe_skill: "缘江烽火图",
yuanjiangfenghuotu: "缘江烽火图",
yuanjiangfenghuotu_info:
- "每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。
根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张以上:〖英姿〗;两张以上:〖好施〗;三张以上:〖涉猎〗;四张以上:〖度势〗;五张以上:可额外选择一项。
锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。",
+ "①每名吴势力角色的出牌阶段限一次,该角色可以将一张装备牌置于“缘江烽火图”上,称之为“烽火”。②根据“烽火”的数量,所有吴势力角色可于其准备阶段选择并获得其中一个技能直到回合结束:一张及以上:〖英姿〗;两张及以上:〖好施〗;三张及以上:〖涉猎〗;四张及以上:〖度势〗;五张及以上:可额外选择一项。③锁定技,当你受到【杀】或锦囊牌造成的伤害后,你将一张“烽火”置入弃牌堆。",
yuanjiangfenghuotu_ab: "江图",
yuanjiangfenghuotu_bg: "图",
wuxin: "悟心",
@@ -23471,8 +23588,9 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
hongfa: "弘法",
hongfa_use: "天兵",
hongfa_respond: "天兵",
+ hongfa_hp: "黄巾天兵符",
hongfa_info:
- "君主技,锁定技,此武将牌明置时,你获得“黄巾天兵符”;准备阶段,若没有“天兵”,你将牌堆顶的X张牌置于“黄巾天兵符”上,称为“天兵”(X为群势力角色的数量)。",
+ "君主技。①只要此武将牌处于明置状态,你便拥有“黄巾天兵符”。②准备阶段,若没有“天兵”,你将牌堆顶的X张牌置于“黄巾天兵符”上,称为“天兵”(X为群势力角色的数量)。",
wendao: "问道",
wendao_info:
"出牌阶段限一次,你可以弃置一张不为【太平要术】的红色牌,然后获得弃牌堆或场上的一张【太平要术】。",
@@ -23480,12 +23598,12 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
huangjintianbingfu_ab: "兵符",
huangjintianbingfu_bg: "符",
huangjintianbingfu_info:
- "锁定技,当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。
当你失去体力时,你可改为将一张“天兵”置入弃牌堆。
与你势力相同的角色可将一张“天兵”当作【杀】使用或打出。",
+ "①锁定技,当你计算群势力角色数时,每一张“天兵”均可视为一名群势力角色。②当你失去体力时,你可改为将一张“天兵”置入弃牌堆。③与你势力相同的角色可将一张“天兵”当作【杀】使用或打出。",
wuhujiangdaqi: "五虎将大旗",
wuhujiangdaqi_ab: "将旗",
wuhujiangdaqi_bg: "旗",
wuhujiangdaqi_info:
- "存活的蜀势力角色的技能按以下规则改动:
武圣:将“红色牌”改为“任意牌”
咆哮:增加描述“你使用的【杀】无视其他角色的防具”
龙胆:增加描述“你发动〖龙胆〗使用或打出牌时摸一张牌”
烈弓:增加描述“你的攻击范围+1”
铁骑:将“一张明置的武将牌”改为“所有明置的武将牌”",
+ "存活的蜀势力角色的技能按以下规则改动:
武圣:将“红色牌”改为“任意牌”
咆哮:增加描述“你使用的【杀】无视其他角色的防具”
龙胆:增加描述“你发动〖龙胆〗使用或打出牌时摸一张牌”
铁骑:将“一张明置的武将牌”改为“所有明置的武将牌”
烈弓:增加描述“你的攻击范围+1”",
zhangwu: "章武",
zhangwu_info:
"锁定技。当【飞龙夺凤】进入弃牌堆或其他角色的装备区后,你获得之。当你不因使用而失去【飞龙夺风】时,你展示此牌,将此牌置于牌堆底并摸两张牌。",
@@ -23981,7 +24099,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
guozhan_decade: "十年踪迹十年心",
guozhan_others: "其他",
- // 语音部分
+ // 台词部分
"#gz_zhonghui:die": "吾机关算尽,却还是棋错一着……",
"#gzzhaoxin1": "行明动正,何惧他人讥毁。",
"#gzzhaoxin2": "大业之举,岂因宵小而动?",
@@ -24133,7 +24251,6 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"#gz_sunjian:die": "有埋伏!呃……啊!!",
"#gz_xiaoqiao:die": "公瑾,我先走一步……",
"#gz_re_taishici:die": "无妄之灾,难以避免……",
- "#buqu1": "哼,这点小伤算什么!",
"#gz_zhoutai:die": "敌众我寡,无力回天……",
"#guzheng2": "固国安邦,居当如是!",
"#gz_zhangzhang:die": "竭力尽智,死而无憾……",
@@ -24208,21 +24325,46 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"#jizhao2": "王业不偏安,起师再兴汉!",
"#rerende_gz_jun_liubei1": "勿以恶小而为之,勿以善小而不为。",
"#rerende_gz_jun_liubei2": "君才十倍于丕,必能安国成事。",
- "#gz_jun_liubei:die": "若嗣子可辅,辅之。如其不才,君可自取……",
+ "#shouyue": "布德而昭仁,见旗如见朕!",
+ "#shouyue_wusheng1": "关将军雄姿,由你再现!",
+ "#shouyue_wusheng2": "再次威震华雄,必成汉兴佳话!",
+ "#shouyue_paoxiao1": "杀!把他捅成马蜂窝!",
+ "#shouyue_paoxiao2": "昔日长坂坡,今日再咆哮!",
+ "#shouyue_longdan1": "请收好,此乃子龙枪法。",
+ "#shouyue_longdan2": "子龙将助你一臂之力。",
+ "#shouyue_tieji1": "西凉的马蹄声,真好听。",
+ "#shouyue_tieji2": "马家军风采何在?!",
+ "#shouyue_liegong1": "当年老将军冲锋,也是这时机。",
+ "#shouyue_liegong2": "百步穿杨,立功拜将!",
+ "#gz_jun_liubei:die": "若嗣子可辅,辅之;如其不才,君可自取……",
"#wuxin1": "冀悟迷惑之心。",
"#wuxin2": "吾已明此救世之术矣。",
- "#hongfa1": "汝等安心,吾乃大贤良师矣。",
- "#hongfa2": "此法可助汝等脱离苦海。",
+ "#hongfa1": "苍天已死,黄天当立!",
+ "#hongfa2": "汝等安心,吾乃大贤良师也。",
+ "#hongfa3": "此法可助汝等脱离苦海。",
"#huangjintianbingfu1": "此乃天将天兵,尔等妖孽看着!",
"#huangjintianbingfu2": "且作一法,召唤神力!",
- "#hongfa_hp": "吾有天神护体!",
+ "#huangjintianbingfu3": "吾有天神护体!",
"#wendao1": "诚心求天地之道,救世之法。",
"#wendao2": "求太平之法以安天下。",
"#gz_jun_zhangjiao:die": "天,真要灭我……",
- "#jiahe1": "有敌来犯,速速御敌。",
- "#jiahe2": "来,扶孤上马迎敌!",
+ "#jiahe": "嘉禾生,大吴兴!",
+ "#yuanjiangfenghuotu1": "保卫国家,人人有责!",
+ "#yuanjiangfenghuotu2": "连绵的烽火,就是对敌人最好的震慑!",
+ "#yuanjiangfenghuotu3": "有敌来犯,速速御敌!",
+ "#yuanjiangfenghuotu4": "来,扶孤上马迎敌!",
+ "#jiahe_reyingzi1": "大吴江山,儒将辈出。",
+ "#jiahe_reyingzi2": "千夫奉儒将,百兽伏麒麟。",
+ "#jiahe_haoshi1": "朋友有难,当倾囊相助。",
+ "#jiahe_haoshi2": "好东西,就要跟朋友分享。",
+ "#jiahe_shelie1": "军中多务,亦当涉猎。",
+ "#jiahe_shelie2": "少说话,多看书。",
+ "#jiahe_duoshi1": "广施方略,以观其变。",
+ "#jiahe_duoshi2": "莫慌,观察好局势再做行动。",
"#lianzi1": "税以足食,赋以足兵。",
"#lianzi2": "府库充盈,国家方能强盛!",
+ "#zhiheng_gz_jun_sunquan1": "二宫并阙,孤之所愿。",
+ "#zhiheng_gz_jun_sunquan2": "鲁王才兼文武,堪比太子。",
"#jubao1": "四海之宝,孤之所爱。",
"#jubao2": "夷洲,扶南,辽东,皆大吴臣邦也!",
"#gz_jun_sunquan:die": "朕的江山,要倒下了么……",
@@ -24272,7 +24414,12 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"#jianglue1": "奇谋为短,将略为要。",
"#jianglue2": "为将者,需有谋略。",
"#gz_wangping:die": "无当飞军,也有困于深林之时……",
- "#gz_fazheng:die": "辅翼既折,蜀汉衰矣……",
+ "#fz_wusheng": "武节不减,圣德加身。",
+ "#fz_new_paoxiao": "刚勇奋战,绝不退缩!",
+ "#fz_new_longdan": "盘龙卧旋,攻防无解。",
+ "#fz_new_tieji": "战骑铁甲,撼动踏阵。",
+ "#fz_liegong": "挽弓箭出,流火漫天。",
+ "#fz_xinkuanggu": "猎战沙场,我的乐趣。",
"#gz_wuguotai:die": "卿等,务必用心辅佐仲谋……",
"#keshou1": "仁以待民,自处不败之势。",
"#keshou2": "宽济百姓,则得战前养备之机。",
@@ -24282,12 +24429,18 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
"#gzfudi2": "绣虽有降心,奈何贵营难容。",
"#drlt_congjian1": "听君谏言,去危亡,保宗祀!",
"#gz_zhangxiu:die": "若失文和,吾将何归?",
- "#jianan1": "行为军锋,还为后拒!",
- "#jianan2": "行为军锋,还为后拒!",
+ "#jianan": "设使天下无孤,不知几人称帝,几人称王?",
+ "#wuziliangjiangdao1": "行为军锋,还为后拒!",
+ "#wuziliangjiangdao2": "国之良将,五子为先。",
+ "#jianan_tuxi": "以百破万,让孤再看一次!",
+ "#jianan_qiaobian": "孤之兵道,此一时,彼一时。",
+ "#jianan_xiaoguo": "使孤梦回辽东者,卿之雄风也!",
+ "#jianan_jieyue": "孤之股肱,谁敢不从?嗯?",
+ "#jianan_duanliang": "孤以为断粮如断肠,卿意下如何?",
"#huibian1": "吾任天下之智力,以道御之,无所不可。",
- "#huibian2": "青青子衿,悠悠我心,但为君故,沉吟至今。",
+ "#huibian2": "青青子衿,悠悠我心。但为君故,沉吟至今。",
"#gzzongyu1": "驾六龙,乘风而行。行四海,路下之八邦。",
- "#gzzongyu2": "齐桓之功,为霸之首,九合诸侯,一匡天下。",
+ "#gzzongyu2": "齐桓之功,为霸之首。九合诸侯,一匡天下!",//配音错误?,应为:齐桓之功,为霸之道
"#gz_jun_caocao:die": "神龟虽寿,犹有竟时。腾蛇乘雾,终为土灰……",
"#sanchen1": "陈书弼国,当一而再、再而三。",
"#gz_duyu:die": "金瓯尚缺,死难瞑目……",
diff --git a/mode/single.js b/mode/single.js
index caab69e66..ab36f47a0 100644
--- a/mode/single.js
+++ b/mode/single.js
@@ -1562,6 +1562,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) {
},
get: {
attitude: function (from, to) {
+ if (!from || !to) return 0;
if (from.identity == to.identity) return 10;
return -10;
},
diff --git a/noname/get/index.js b/noname/get/index.js
index cd8092f72..c4826002b 100644
--- a/noname/get/index.js
+++ b/noname/get/index.js
@@ -974,6 +974,16 @@ export class Get {
return target;
}
+ /**
+ * 用于将HTML代码转换为纯文本。
+ * @param { string } htmlContent
+ * @returns { string }
+ */
+ plainText(htmlContent) {
+ var parser = new DOMParser();
+ var doc = parser.parseFromString(htmlContent || '', 'text/html');
+ return doc.body.textContent || doc.body.innerText;
+ }
inpilefull(type) {
var list = [];
for (var i in lib.cardPile) {
@@ -1551,12 +1561,7 @@ export class Get {
if (func._filter_args) {
return "_noname_func:" + JSON.stringify(get.stringifiedResult(func._filter_args, 3));
}
- const { Marshal, Sandbox } = security.importSandbox();
- const domain = Marshal.getMarshalledDomain(func);
- if (domain) {
- const sandbox = Sandbox.from(domain);
- if (sandbox && "client" in sandbox) throw new Error("不应该二次扩散远程代码");
- }
+ const { Marshal } = security.importSandbox();
const str = Marshal.decompileFunction(func);
// js内置的函数
if (/\{\s*\[native code\]\s*\}/.test(str)) return "_noname_func:function () {}";
diff --git a/noname/library/element/content.js b/noname/library/element/content.js
index 86db226b8..42c90d99e 100644
--- a/noname/library/element/content.js
+++ b/noname/library/element/content.js
@@ -2725,7 +2725,7 @@ export const Content = {
if (get.itemtype(targets) === "player") {
targets = [targets];
}
- if (info.popup != false && !info.direct) {
+ if (info.popup != false && !info.direct && !("skill_popup" in result && !Boolean(result["skill_popup"]))) {
let popup_info = event.skill;
if (typeof info.popup === "string") popup_info = [event.skill, info.popup];
if (info.logLine === false) player.logSkill(popup_info, false, info.line);
@@ -3152,7 +3152,6 @@ export const Content = {
game.syncState();
game.addVideo("phaseChange", player);
if (game.phaseNumber == 1) {
- delete player._start_cards;
if (lib.configOL.observe) {
lib.configOL.observeReady = true;
game.send("server", "config", lib.configOL);
@@ -5889,6 +5888,7 @@ export const Content = {
} else if (!event.dialog.noforcebutton) {
event.dialog.classList.add("forcebutton-auto");
}
+ directh = false;
} else {
event.dialog.add([hs, "blank"]);
}
@@ -6083,6 +6083,7 @@ export const Content = {
} else if (!event.dialog.noforcebutton) {
event.dialog.classList.add("forcebutton-auto");
}
+ directh = false;
} else {
event.dialog.add([hs, "blank"]);
}
@@ -6300,6 +6301,7 @@ export const Content = {
} else if (!event.dialog.noforcebutton) {
event.dialog.classList.add("forcebutton-auto");
}
+ directh = false;
} else {
event.dialog.add([hs, "blank"]);
}
diff --git a/noname/library/element/player.js b/noname/library/element/player.js
index 4ce81a277..5b51c9a1e 100644
--- a/noname/library/element/player.js
+++ b/noname/library/element/player.js
@@ -4454,6 +4454,7 @@ export class Player extends HTMLDivElement {
next.func = arguments[i];
}
}
+ return next;
}
discoverCard(list) {
var next = game.createEvent("discoverCard");
@@ -7073,7 +7074,7 @@ export class Player extends HTMLDivElement {
node = ui.create.div(".card.mark.drawinghidden");
ui.create.div(".background.skillmark", node).innerHTML = get.translation(name)[0];
} else {
- if (!lib.character[name]) return;
+ if (!get.character(name)) return;
node = ui.create.div(".card.mark.drawinghidden").setBackground(name, "character");
}
this.node.marks.insertBefore(node, this.node.marks.childNodes[1]);
@@ -9027,9 +9028,7 @@ export class Player extends HTMLDivElement {
*/
hasSkillTag(tag, hidden, arg, globalskill) {
var skills = this.getSkills(hidden);
- if (globalskill) {
- skills.addArray(lib.skill.global);
- }
+ if (globalskill !== false) skills.addArray(lib.skill.global);
game.expandSkills(skills);
for (var i = 0; i < skills.length; i++) {
var info = lib.skill[skills[i]];
diff --git a/noname/library/index.js b/noname/library/index.js
index 592d3d2e5..bae2b6f50 100644
--- a/noname/library/index.js
+++ b/noname/library/index.js
@@ -11999,6 +11999,7 @@ export class Library {
},
},
};
+ /** @type {Object} */
character = new Proxy(
{},
{
@@ -12040,8 +12041,8 @@ export class Library {
lib.node.observing.push(this);
this.send("reinit", lib.configOL, get.arenaState(), game.getState ? game.getState() : {}, game.ip, game.players[0].playerid, null, _status.cardtag);
// 没有系统提示的接口喵?
- game.log("玩家 ", `#y${config.nickname}`, " 进入房间观战");
- game.me.chat(`玩家 ${config.nickname} 进入房间观战`);
+ game.log("玩家 ", `#y${get.plainText(config.nickname)}`, " 进入房间观战");
+ game.me.chat(`玩家 ${get.plainText(config.nickname)} 进入房间观战`);
if (!ui.removeObserve) {
ui.removeObserve = ui.create.system(
"移除旁观",
diff --git a/noname/ui/create/index.js b/noname/ui/create/index.js
index d7b4c4258..a837b0a0e 100644
--- a/noname/ui/create/index.js
+++ b/noname/ui/create/index.js
@@ -2770,7 +2770,7 @@ export class Create {
// }
ui.sortCard = ui.create.system("整理手牌", function () {
- if (!game.me) return;
+ if (!game.me || game.me.hasSkillTag("noSortCard")) return;
var hs = game.me.getCards("h");
if (!hs.length) return;
game.addVideo("lose", game.me, [get.cardsInfo(hs), [], [], []]);
diff --git a/noname/util/sandbox.js b/noname/util/sandbox.js
index 76940e44b..148259267 100644
--- a/noname/util/sandbox.js
+++ b/noname/util/sandbox.js
@@ -41,6 +41,28 @@ const SandboxSignal_ListMonitor = Symbol("ListMonitor");
const SandboxSignal_ExposeInfo = Symbol("ExposeInfo");
const SandboxSignal_TryFunctionRefs = Symbol("TryFunctionRefs");
+// 用于适配 < Chrome 84 的设备
+const WeakRef = window.WeakRef || class WeakRef {
+ /**
+ * @param {any} target
+ */
+ constructor(target) {
+ this.target = target;
+ }
+
+ /**
+ * @returns {any}
+ */
+ deref() {
+ return this.target;
+ }
+
+ /**
+ * @type {"WeakRef"}
+ */
+ [Symbol.toStringTag] = "WeakRef";
+};
+
/**
* ```plain
* 判断是否为基元类型
@@ -914,19 +936,18 @@ class NativeWrapper {
const prototype = NativeWrapper.#currentFunction.prototype;
// 根据是否装箱进行不同的封装
const wrapped = (flags & 2)
- ? function (...args) {
+ ? function (/** @type {any[]} */ ...args) {
const list = args.map(a =>
NativeWrapper.boxCallback(a, prototype));
// @ts-ignore
return ContextInvoker1(func, this, list);
}
- : function (...args) {
+ : function (/** @type {any[]} */ ...args) {
// @ts-ignore
return ContextInvoker1(func, this, args);
};
// 构造原型链
- sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@@ -945,17 +966,16 @@ class NativeWrapper {
const prototype = NativeWrapper.#currentFunction.prototype;
// 根据是否装箱进行不同的封装
const wrapped = (flags & 2)
- ? function (...args) {
+ ? function (/** @type {any[]} */ ...args) {
const list = args.map(a =>
NativeWrapper.boxCallback(a, prototype));
return ContextInvoker2(func, list, new.target);
}
- : function (...args) {
+ : function (/** @type {any[]} */ ...args) {
return ContextInvoker2(func, args, new.target);
};
// 构造原型链
- sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@@ -977,7 +997,6 @@ class NativeWrapper {
};
// 构造原型链
- sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@@ -993,14 +1012,13 @@ class NativeWrapper {
static wrapSetter(func) {
// @ts-ignore
const prototype = NativeWrapper.#currentFunction.prototype;
- const wrapped = function (value) {
+ const wrapped = function (/** @type {ProxyConstructor} */ value) {
// @ts-ignore
return ContextInvoker1(func, this,
[NativeWrapper.boxCallback(value, prototype)]);
};
// 构造原型链
- sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
return wrapped;
}
@@ -1025,7 +1043,7 @@ class NativeWrapper {
// 缓存不存在则创建
wrapped = ContextInvokerCreator({
unboxed, // 向封装函数提供unboxed函数
- }, function (thiz, args, newTarget) {
+ }, function (/** @type {any} */ thiz, /** @type {readonly any[]} */ args, /** @type {(new (...args: any) => any) | undefined} */ newTarget) {
return newTarget
// @ts-ignore
? Reflect.construct(this.unboxed, args, newTarget)
@@ -1034,13 +1052,12 @@ class NativeWrapper {
});
// 设置暴露器
- wrapped[SandboxExposer] = (signal) => {
+ wrapped[SandboxExposer] = (/** @type {symbol} */ signal) => {
if (signal === NativeWrapper.#unboxedFunction)
return unboxed;
};
// 构造原型链
- sealObjectTree(wrapped);
Reflect.setPrototypeOf(wrapped, prototype);
NativeWrapper.#boxedMap.set(unboxed, wrapped);
}
@@ -1132,6 +1149,9 @@ class DomainMonitors {
return;
}
+ /**
+ * @param {{ [x: number]: Set; }} actionMap
+ */
function addToActionMap(actionMap) {
for (const action of actions) {
let monitorMap = actionMap[action];
@@ -1205,6 +1225,9 @@ class DomainMonitors {
return;
}
+ /**
+ * @param {{ [x: number]: Set; }} actionMap
+ */
function removeFromActionMap(actionMap) {
for (const action of actions) {
const monitorMap = actionMap[action];
@@ -1465,12 +1488,19 @@ class DomainMonitors {
stopPropagation() {
result.stopPropagation = true;
},
+ /**
+ * @param {string} name
+ * @param {any} value
+ */
overrideParameter(name, value) {
if (!(name in indexMap))
throw new TypeError(`参数 ${name} 没有找到`);
args[indexMap[name]] = value;
},
+ /**
+ * @param {undefined} value
+ */
setReturnValue(value) {
result.returnValue = value;
},
@@ -2270,10 +2300,18 @@ class Marshal {
const errorCtor = target.constructor;
const mappedCtor = Globals.mapTo(errorCtor, sourceDomain, targetDomain);
+ // // 立即报告错误,而不是通过封送报错
+ // const window = Domain.topDomain[SandboxExposer](SandboxSignal_GetWindow);
+ // window.onunhandledrejection && window.onunhandledrejection({ promise: Promise.reject(target) });
+
if (mappedCtor) {
const newError = new mappedCtor();
- Object.defineProperties(newError,
- Object.getOwnPropertyDescriptors(target));
+ const stack = String(target.stack);
+ Reflect.defineProperty(newError, 'stack', {
+ get: () => () => stack,
+ set: () => { },
+ configurable: false,
+ });
return newError;
}
}
@@ -2923,6 +2961,7 @@ class Domain {
* 确保 Array.isArray 对代理数组放宽
* ```
*
+ * @param {Domain} domain
* @param {any} array
* @returns {boolean}
*/
@@ -3212,14 +3251,28 @@ class Sandbox {
}
const handler = {
+ /**
+ * @param {FunctionConstructor} target
+ * @param {any} thisArg
+ * @param {any[]} argArray
+ */
apply(target, thisArg, argArray) {
return functionCtor(target, argArray);
},
+ /**
+ * @param {FunctionConstructor} target
+ * @param {any[]} argArray
+ * @param {any} newTarget
+ */
construct(target, argArray, newTarget) {
return functionCtor(target, argArray);
},
};
+ /**
+ * @param {object} prototype
+ * @param {any} newCtor
+ */
function rewriteCtor(prototype, newCtor) {
const descriptor = Object.getOwnPropertyDescriptor(prototype, 'constructor')
|| { configurable: true, writable: true, enumerable: false };
@@ -3277,8 +3330,13 @@ class Sandbox {
while (code.endsWith(";"))
code = code.slice(0, -1);
- if (!/[;\n\r]$/.test(code))
- code = `return (${code})`;
+ if (!/[;\n\r]$/.test(code)) {
+ const newCode = `return (${code})`;
+ try {
+ new Function(newCode);
+ code = newCode;
+ } catch (e) { }
+ }
return thiz.exec(code);
}
@@ -3510,6 +3568,7 @@ class Sandbox {
// 进行语法检查,防止注入
new thiz.#domainFunction(code);
+ const passThis = !("this" in context);
const executingScope = Sandbox.#executingScope[Sandbox.#executingScope.length - 1];
const scope = inheritScope && executingScope || thiz.#scope;
const contextName = Sandbox.#makeName("_", scope);
@@ -3572,7 +3631,7 @@ class Sandbox {
// 构建陷入的沙盒闭包
// 同时对返回值进行封送
- return ((/** @type {any} */ ...args) => {
+ return /** @this {any} */ function (/** @type {any} */ ...args) {
const prevDomain = Domain.current;
const domainAction = () => {
// 指定执行域
@@ -3580,11 +3639,39 @@ class Sandbox {
Sandbox.#executingScope.push(scope);
try {
+ // 传递 `this`、以及函数参数
+ if (passThis)
+ context.this = Marshal[SandboxExposer2]
+ (SandboxSignal_Marshal, this, domain);
argumentList = Marshal[SandboxExposer2]
(SandboxSignal_MarshalArray, args, domain);
+
+ // 调用闭包函数
const result = raw.call(null, intercepter);
+
+ // 封送返回结果
return Marshal[SandboxExposer2]
(SandboxSignal_Marshal, result, prevDomain);
+ // } catch (e) {
+ // // 立即报告错误
+ // const window = Domain.topDomain[SandboxExposer](SandboxSignal_GetWindow);
+ // // @ts-ignore
+ // const stack = String(e.stack);
+ // const line = stack.split("\n")[1];
+ // const match = /:(\d+):\d+\)/.exec(line);
+ // if (match) {
+ // const index = parseInt(match[1]) - 5;
+ // const lines = code.split("\n");
+ // let codeView = "";
+ // for (let i = index - 4; i < index + 5; i++) {
+ // if (i < 0 || i >= lines.length)
+ // continue;
+ // codeView += `${i + 1}|${i == index ? "⚠️" : " "}${lines[i]}\n`;
+ // }
+ // // @ts-ignore
+ // window.alert(`Sandbox内执行的代码出现错误:\n${stack}\n----------\n${codeView}\n----------`);
+ // }
+ // throw e; // 不再向上抛出异常
} finally {
Sandbox.#executingScope.pop();
}
@@ -3595,7 +3682,7 @@ class Sandbox {
return Marshal[SandboxExposer2]
(SandboxSignal_TrapDomain, domain, domainAction);
- }).bind(null); // 编译函数不应该发送
+ };
}
/**
@@ -3759,7 +3846,7 @@ class Sandbox {
Object.defineProperties(rawScope, descriptors);
}
- static #makeName = function (prefix, conflict) {
+ static #makeName = function (/** @type {string} */ prefix, /** @type {any} */ conflict) {
let builtName;
do {
@@ -3782,6 +3869,9 @@ class Sandbox {
}
}
+/**
+ * @param {any} clazz
+ */
function sealClass(clazz) {
sealObjectTree(clazz);
@@ -3792,9 +3882,12 @@ function sealClass(clazz) {
}
// FREEZE FROM SOUL!
+/**
+ * @param {any} obj
+ */
function sealObjectTree(obj) {
// @ts-ignore
- sealObject(obj, o => {
+ sealObject(obj, (/** @type {object} */ o) => {
if (!Reflect.isExtensible(o)) // 防止1103
return;
if (o === obj)
@@ -3804,6 +3897,9 @@ function sealObjectTree(obj) {
});
}
+/**
+ * @param {any} obj
+ */
function sealObject(obj, freeze = Object.freeze) {
if (isPrimitive(obj))
return;
diff --git a/noname/util/security.js b/noname/util/security.js
index 7159cdd1c..b24e4177e 100644
--- a/noname/util/security.js
+++ b/noname/util/security.js
@@ -2,7 +2,7 @@
// 但沙盒不会也没有办法维护恶意服务器/房主对于游戏规则的破坏,请玩家尽量选择官方或其他安全的服务器,同时选择一个受信任的玩家作为房主
// 是否强制所有模式下使用沙盒
-const SANDBOX_FORCED = true;
+const SANDBOX_FORCED = false;
// 是否启用自动测试
const SANDBOX_AUTOTEST = false;
// 是否禁用自动测试延迟
@@ -415,6 +415,7 @@ async function initSecurity({
return;
loadPolyfills();
+ initSerializeNeeded();
initIsolatedEnvironment();
// 不允许被远程代码访问的game函数
@@ -810,6 +811,41 @@ function initIsolatedEnvironment() {
rewriteCtor(defaultAsyncGeneratorFunction.prototype, ModAsyncGeneratorFunction);
}
+/**
+ * ```plain
+ * 初始化需要额外序列化的函数
+ *
+ * 适配扩展,当在skillcontent里面调用皮切的playEffect时会报错
+ * ```
+ */
+function initSerializeNeeded() {
+ const structuredClone = window.structuredClone;
+ const deepClone = (/** @type {any} */ obj) => {
+ try {
+ return structuredClone(obj);
+ } catch (e) {
+ return obj;
+ }
+ };
+
+ /** @type {Array<[string, number[]]>} */
+ const funcList = [
+ ["Worker.prototype.postMessage", [0]],
+ ];
+
+ for (const [funcCode, argIndexes] of funcList) {
+ const originalFunc = new Function(`return ${funcCode}`)();
+ const newFunc = /** @this {any} */ function (/** @type {any[]} */ ...args) {
+ for (const index of argIndexes)
+ args[index] = deepClone(args[index]);
+
+ return originalFunc.apply(this, args);
+ };
+
+ new Function("_", `${funcCode} = _;`)(newFunc);
+ }
+}
+
/**
* ```plain
* 加载当前的垫片函数