diff --git a/crescendo/SimpleAvZ/SimpleAvZ/cannon.h b/crescendo/SimpleAvZ/SimpleAvZ/cannon.h index 9705c26..95a332b 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/cannon.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/cannon.h @@ -8,18 +8,18 @@ class CobOperator : public AvZ::PaoOperator { public: - // 创建 CobOperator. 指定要用炮尾在哪些列的炮. - // *** 使用示例: - // CobOperator c1(1)---------只用炮尾在1列的炮 - // CobOperator c45(4, 5)-----只用炮尾在4或5列的炮 + // Create CobOperator and specify cobs with tail at which cols to use. + // *** Usage: + // CobOperator c1(1)--------- Only use cobs with tail at col 1 + // CobOperator c45(4, 5)----- Only use cobs with tail at col 4 or 5 template CobOperator(Args... args) : AvZ::PaoOperator() { for (int col : {args...}) { - validate_cob_col(col, "CobOperator 构造函数"); + validate_cob_col(col, "CobOperator constructor"); if (cob_cols.count(col)) { - _SimpleAvZInternal::error("CobOperator 构造函数", "不可重复指定炮尾列\n重复的炮尾列: #", col); + _SimpleAvZInternal::error("CobOperator constructor", "Duplicate cob tail cols: #", col); } cob_cols.insert(col); } @@ -30,14 +30,15 @@ class CobOperator : public AvZ::PaoOperator { { } - // 发射一组并炸炮. - // 若省略行数, 默认六行场地炸 2,5 路, 五行场地炸 2,4 路. 若省略列数, 默认炸 9 列. - // *** 使用示例: - // c.PP(318)-----------------炸(2,9)与(5,9), 318cs生效 - // c.PP(318, 8)--------------炸(2,8)与(5,8) - // c.PP(318, {8, 9})---------炸(2,8)与(5,9) - // c.PP(318, {2, 6}, 9)------炸(2,9)与(6,9) - // c.PP(after(110), ...)-----用法同上, 延迟110cs生效 + // Fire two cobs. + // If rows are omitted, they default to row 2 & 5 for PE/FE and row 2 & 4 for other scenes. + // If col is omitted, it defaults to 9. + // *** Usage: + // c.PP(318)----------------- Fire (2,9) and (5,9), taking effect at 318cs + // c.PP(318, 8)-------------- Fire (2,8) and (5,8) + // c.PP(318, {8, 9})--------- Fire (2,8) and (5,9) + // c.PP(318, {2, 6}, 9)------ Fire (2,9) and (6,9) + // c.PP(after(110), ...)----- Take effect after 110cs void PP(Time time, const std::array& rows, float col) { cob_internal(time, {{rows[0], col}, {rows[1], col}}, "PP"); @@ -59,14 +60,15 @@ class CobOperator : public AvZ::PaoOperator { PP(time, {9, 9}); } - // 发射一组拦截炮. - // 若省略行数, 六行场地炸 1,5 路, 五行场地炸 1,4 路. 若省略列数, 默认炸 9 列. - // *** 使用示例: - // c.DD(318)-----------------炸(1,9)与(5,9), 318cs生效 - // c.DD(318, 8)--------------炸(1,8)与(5,8) - // c.DD(318, {8, 9})---------炸(1,8)与(5,9) - // c.DD(318, {2, 5}, 3.5)----炸(2,3.5)与(5,3.5) - // c.DD(after(110), ...)-----用法同上, 延迟110cs生效 + // Fire two interception cobs. + // If rows are omitted, they default to row 1 & 5 for PE/FE and row 1 & 4 for other scenes. + // If col is omitted, it defaults to 9. + // *** Usage: + // c.DD(318)----------------- Fire (1,9) and (5,9), taking effect at 318cs + // c.DD(318, 8)-------------- Fire (1,8) and (5,8) + // c.DD(318, {8, 9})--------- Fire (1,8) and (5,9) + // c.DD(318, {2, 5}, 3.5)---- Fire (2,3.5) and (5,3.5) + // c.DD(after(110), ...)----- Take effect after 110cs void DD(Time time, const std::array& rows, float col) { std::vector positions; @@ -91,11 +93,12 @@ class CobOperator : public AvZ::PaoOperator { DD(time, {9, 9}); } - // 发射一门炮. 可指明要用哪门炮. - // *** 使用示例: - // c.P(318, 2, 9)-----------------炸(2,9), 318cs生效 - // c.P(318, 1, 1, 2, 8)-----------使用1-1炮炸(2,8) - // c.P(after(110), ...)-----------用法同上, 延迟110cs生效 + // Fire one cob. + // You may specify which cob to use. + // *** Usage: + // c.P(318, 2, 9)----------------- Fire (2,9), taking effect at 318cs + // c.P(318, 1, 1, 2, 8)----------- Use cob at 1-1 to fire (2,8) + // c.P(after(110), ...)----------- Take effect after 110cs void P(Time time, int row, float col) { cob_internal(time, {{row, col}}, "P"); @@ -106,26 +109,26 @@ class CobOperator : public AvZ::PaoOperator { cob_internal(time, {{row, col}}, "P", {cob_row, cob_col}); } - // 发射分离炮. - // *** 使用示例: - // c.B(304, 5, 8.225)-----炸(5, 8.225), 304cs生效 + // Fire one separation cob. + // *** Usage: + // c.B(304, 5, 8.225)----- Fire (5, 8.225), taking effect at 304cs void B(Time time, int row, float col) { cob_internal(time, {{row, col}}, "B"); } - // 发射拦截炮. - // *** 使用示例: - // c.D(395, 1, 9)-----炸(1,9), 395cs生效 + // Fire one interception cob. + // *** Usage: + // c.D(395, 1, 9)----- Fire (1,9), taking effect at 395cs void D(Time time, int row, float col) { cob_internal(time, {{row, col}}, "D"); } - // 不使用特定炮. - // *** 使用用例: - // c.ExcludeCob(3, 5)---------不使用3-5炮, 游戏开始时起效[外] - // c.ExcludeCob(400, ...)-----400cs起效 + // Exclude certain cobs from being used. + // *** Usage: + // c.ExcludeCob(3, 5)--------- Do not use cob at 3-5, effective since game start [EXT] + // c.ExcludeCob(400, ...)----- Effective since 400cs void ExcludeCob(Time time, int row, int col) { _SimpleAvZInternal::get_effect_time_and_set_time(time, "ExcludeCob"); @@ -138,9 +141,9 @@ class CobOperator : public AvZ::PaoOperator { exclude_cob_internal(row, col); } - // 重置为使用所有炮. - // *** 使用用例: - // c.ResetCob(400)-----重置为使用所有炮, 400cs起效 + // Reset to use all cobs. + // *** Usage: + // c.ResetCob(400)----- Reset to use all cobs, effective since 400cs void ResetCob(Time time) { _SimpleAvZInternal::get_effect_time_and_set_time(time, "ResetCob"); @@ -170,14 +173,14 @@ class CobOperator : public AvZ::PaoOperator { { int max_row = _SimpleAvZInternal::is_visually_six_rows() ? 6 : 5; if (row < 1 || row > max_row) { - _SimpleAvZInternal::error(func_name, "炮行数应在1~#内\n炮行数: #", max_row, row); + _SimpleAvZInternal::error(func_name, "Cob row should be within 1~#: #", max_row, row); } } void validate_cob_col(int col, const std::string& func_name) { if (col < 1 || col > 8) { - _SimpleAvZInternal::error(func_name, "炮尾列应在1~8内\n炮尾列: #", col); + _SimpleAvZInternal::error(func_name, "Cob col should be within 1~8: #", col); } } @@ -204,10 +207,10 @@ class CobOperator : public AvZ::PaoOperator { for (const auto& pos : positions) { if (pos.row < 1 || pos.row > max_row) { - _SimpleAvZInternal::error(func_name, "落点行应在1~#内\n落点行: #", max_row, pos.row); + _SimpleAvZInternal::error(func_name, "Cob hit row should be within 1~#: #", max_row, pos.row); } if (pos.col < 0 || pos.col > 10) { - _SimpleAvZInternal::error(func_name, "落点列应在0.0~10.0内\n落点列: #", pos.col); + _SimpleAvZInternal::error(func_name, "Cob hit col should be within 0.0~10.0: #", pos.col); } } @@ -272,14 +275,15 @@ class CobOperator : public AvZ::PaoOperator { CobOperator cob_operator; -// 发射一组并炸炮. -// 若省略行数, 默认六行场地炸 2,5 路, 五行场地炸 2,4 路. 若省略列数, 默认炸 9 列. -// *** 使用示例: -// PP(318)-----------------炸(2,9)与(5,9), 318cs生效 -// PP(318, 8)--------------炸(2,8)与(5,8) -// PP(318, {8, 9})---------炸(2,8)与(5,9) -// PP(318, {2, 6}, 9)------炸(2,9)与(6,9) -// PP(after(110), ...)-----用法同上, 延迟110cs生效 +// Fire two cobs. +// If rows are omitted, they default to row 2 & 5 for PE/FE and row 2 & 4 for other scenes. +// If col is omitted, it defaults to 9. +// *** Usage: +// PP(318)----------------- Fire (2,9) and (5,9), taking effect at 318cs +// PP(318, 8)-------------- Fire (2,8) and (5,8) +// PP(318, {8, 9})--------- Fire (2,8) and (5,9) +// PP(318, {2, 6}, 9)------ Fire (2,9) and (6,9) +// PP(after(110), ...)----- Take effect after 110cs void PP(Time time, const std::array& rows, float col) { cob_operator.PP(time, rows, col); @@ -300,14 +304,15 @@ void PP(Time time) cob_operator.PP(time); } -// 发射一组拦截炮. -// 若省略行数, 六行场地炸 1,5 路, 五行场地炸 1,4 路. 若省略列数, 默认炸 9 列. -// *** 使用示例: -// DD(318)-----------------炸(1,9)与(5,9), 318cs生效 -// DD(318, 8)--------------炸(1,8)与(5,8) -// DD(318, {8, 9})---------炸(1,8)与(5,9) -// PP(318, {2, 5}, 3.5)----炸(2,3.5)与(5,3.5) -// DD(after(110), ...)-----用法同上, 延迟110cs生效 +// Fire two interception cobs. +// If rows are omitted, they default to row 1 & 5 for PE/FE and row 1 & 4 for other scenes. +// If col is omitted, it defaults to 9. +// *** Usage: +// DD(318)----------------- Fire (1,9) and (5,9), taking effect at 318cs +// DD(318, 8)-------------- Fire (1,8) and (5,8) +// DD(318, {8, 9})--------- Fire (1,8) and (5,9) +// DD(318, {2, 5}, 3.5)---- Fire (2,3.5) and (5,3.5) +// DD(after(110), ...)----- Take effect after 110cs void DD(Time time, const std::array& rows, float col) { cob_operator.DD(time, rows, col); @@ -328,11 +333,12 @@ void DD(Time time) cob_operator.DD(time); } -// 发射一门炮. 可指明要用哪门炮. -// *** 使用示例: -// P(318, 2, 9)-----------------炸(2,9), 318cs生效 -// P(318, 1, 1, 2, 8)-----------使用1-1炮炸(2,8) -// P(after(110), ...)-----------用法同上, 延迟110cs生效 +// Fire one cob. +// You may specify which cob to use. +// *** Usage: +// P(318, 2, 9)----------------- Fire (2,9), taking effect at 318cs +// P(318, 1, 1, 2, 8)----------- Use cob at 1-1 to fire (2,8) +// P(after(110), ...)----------- Take effect after 110cs void P(Time time, int row, float col) { cob_operator.P(time, row, col); @@ -343,26 +349,26 @@ void P(Time time, int cob_row, int cob_col, int row, float col) cob_operator.P(time, cob_row, cob_col, row, col); } -// 发射分离炮. -// *** 使用示例: -// B(304, 5, 8.225)-----炸(5, 8.225), 304cs生效 +// Fire one separation cob. +// *** Usage: +// B(304, 5, 8.225)----- Fire (5, 8.225), taking effect at 304cs void B(Time time, int row, float col) { cob_operator.B(time, row, col); } -// 发射拦截炮. -// *** 使用示例: -// D(395, 1, 9)-----炸(1,9), 395cs生效 +// Fire one interception cob. +// *** Usage: +// D(395, 1, 9)----- Fire (1,9), taking effect at 395cs void D(Time time, int row, float col) { cob_operator.D(time, row, col); } -// 不使用特定炮. -// *** 使用用例: -// ExcludeCob(3, 5)---------不使用3-5炮, 游戏开始时起效[外] -// ExcludeCob(400, ...)-----400cs起效 +// Exclude certain cobs from being used. +// *** Usage: +// ExcludeCob(3, 5)--------- Do not use cob at 3-5, effective since game start [EXT] +// ExcludeCob(400, ...)----- Effective since 400cs void ExcludeCob(Time time, int row, int col) { cob_operator.ExcludeCob(time, row, col); @@ -373,9 +379,9 @@ void ExcludeCob(int row, int col) cob_operator.ExcludeCob(row, col); } -// 重置为使用所有炮. -// *** 使用用例: -// ResetCob(400)-----重置为使用所有炮, 400cs起效 +// Reset to use all cobs. +// *** Usage: +// ResetCob(400)----- Reset to use all cobs, effective since 400cs void ResetCob(Time time) { cob_operator.ResetCob(time); diff --git a/crescendo/SimpleAvZ/SimpleAvZ/card.h b/crescendo/SimpleAvZ/SimpleAvZ/card.h index 3b75415..e06cb4f 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/card.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/card.h @@ -190,7 +190,7 @@ std::set get_invalid_plants(int row, const std::string& func_name) case 5: return {GRAVE_BUSTER, LILY_PAD, TANGLE_KELP, SPIKEWEED, SEA_SHROOM, COFFEE_BEAN, CATTAIL, SPIKEROCK}; default: - error(func_name, "不支持的场景: #", AvZ::GetMainObject()->scene()); + error(func_name, "Unknown scene: #", AvZ::GetMainObject()->scene()); return {}; } } @@ -199,13 +199,13 @@ void validate_card_position(const PlantType& plant_type, int row, int col, const { int max_row = is_visually_six_rows() ? 6 : 5; if (row < 1 || row > max_row) { - error(func_name, "用卡行应在1~#内\n用卡行: #", max_row, row); + error(func_name, "Card row should be within 1~#: #", max_row, row); } if (col < 1 || col > 9) { - error(func_name, "用卡列应在1~9内\n用卡列: #", col); + error(func_name, "Card col should be within 1~9: #", col); } if (get_invalid_plants(row, func_name).count(non_imitater(plant_type))) { - error(func_name, "当前场景不可在此行使用此卡片\n卡片: #\n用卡行: #", non_imitater(plant_type), row); + error(func_name, "Cannot use this card in the current scene\nCard: #\nCard row: #", non_imitater(plant_type), row); } } @@ -213,27 +213,28 @@ void validate_shovel_position(int row, int col, const std::string& func_name) { int max_row = is_visually_six_rows() ? 6 : 5; if (row < 1 || row > max_row) { - error(func_name, "铲除行应在1~#内\n铲除行: #", max_row, row); + error(func_name, "Shovel row should be within 1~#: #", max_row, row); } if (col < 1 || col > 9) { - error(func_name, "铲除列应在1~9内\n铲除列: #", col); + error(func_name, "Shovel col should be within 1~9: #", col); } } } // namespace _SimpleAvZInternal -// 铲除植物. 可提供单一坐标, 多行同列. 也可指定要铲除的植物种类. -// *** 使用示例: -// RM(400, SUNFLOWER)-----------于400cs铲除场地上所有小向 -// RM(400, PUMPKIN, 1, 1)-------铲除1-1南瓜(没有则不铲) -// RM(400, 1, 1)----------------铲除1-1, 优先铲除非南瓜 -// RM(400, {1, 2, 5, 6}, 9)-----铲除1,2,5,6路9列, 优先铲除非南瓜 -// RM(after(751), ...)----------用法同上, 延迟751cs生效 +// Shovel plants. +// You may provide a single position, multiple rows with the same column, or a certain plant type to be shoveled. +// *** Usage: +// RM(400, SUNFLOWER)----------- Shovel all sunflowers at 400cs +// RM(400, PUMPKIN, 1, 1)------- Shovel pumpkin at 1-1 (if there is no pumpkin, do nothing) +// RM(400, 1, 1)---------------- Shovel 1-1 (non-pumpkin plants first) +// RM(400, {1, 2, 5, 6}, 9)----- Shovel 1-9, 2-9, 5-9, 6-9 (non-pumpkin plants first) +// RM(after(751), ...)---------- Same usage, taking effect after 751cs void RM(Time time, PlantType target) { target = _SimpleAvZInternal::non_imitater(target); if (target == GRAVE_BUSTER) { - _SimpleAvZInternal::error("RM", "墓碑吞噬者无法铲除"); + _SimpleAvZInternal::error("RM", "Cannot shovel grave buster"); } _SimpleAvZInternal::get_effect_time_and_set_time(time, "RM"); @@ -252,7 +253,7 @@ void RM(Time time, PlantType target, int row, int col) target = _SimpleAvZInternal::non_imitater(target); if (target == GRAVE_BUSTER) { - _SimpleAvZInternal::error("RM", "墓碑吞噬者无法铲除"); + _SimpleAvZInternal::error("RM", "Cannot shovel grave buster"); } _SimpleAvZInternal::validate_shovel_position(row, col, "RM"); @@ -293,16 +294,16 @@ void RM(Time time, int row, int col) RM(time, {{row}}, col); } -// 夜间用原版冰. 自带生效时机修正. -// 若不指定生效时间, 默认在本波 601cs 生效. -// *** 使用示例: -// I(1, 2)------------------于1-2放置原版冰, 601cs生效(完美预判冰) -// I(after(210), 1, 2)------延迟210cs生效(ice3), 推荐在激活炮后使用 -// I(359, 1, 2)-------------359cs生效 +// Use ice in nighttime. Effect time is auto-corrected. +// If effect time is not specified, it defaults to 601cs of the current wave (perfect ice for next wave). +// *** Usage: +// I(1, 2)------------------ Place ice at 1-2, taking effect at 601cs (perfect ice) +// I(after(210), 1, 2)------ Use ice, takeing effect after 210cs (ice3), recommended to be used after activation cobs +// I(359, 1, 2)------------- Use ice, taking effect at 359cs void I(Time time, int row, int col) { if (!_SimpleAvZInternal::is_night_time()) { - _SimpleAvZInternal::error("I", "不可在白昼使用夜间版本的I()\n无需提供用冰位置"); + _SimpleAvZInternal::error("I", "Cannot use nighttime version of I() at daytime\nThere is no need to provide ice position"); } _SimpleAvZInternal::validate_card_position(ICE_SHROOM, row, col, "I"); @@ -316,16 +317,16 @@ void I(int row, int col) I(601, row, col); } -// 夜间用复制冰. 自带生效时机修正. -// 若不指定生效时间, 默认在本波 601cs 生效. -// *** 使用示例: -// M_I(1, 2)------------------于1-2放置复制冰, 601cs生效(完美预判冰) -// M_I(after(210), 1, 2)------延迟210cs生效(ice3), 推荐在激活炮后使用 -// M_I(359, 1, 2)-------------359cs生效 +// Use imitater ice in nighttime. Effect time is auto-corrected. +// If effect time is not specified, it defaults to 601cs of the current wave (perfect ice for next wave). +// *** Usage: +// M_I(1, 2)------------------ Place imitater ice at 1-2, taking effect at 601cs (perfect ice) +// M_I(after(210), 1, 2)------ Use imitater ice, takeing effect after 210cs (ice3), recommended to be used after activation cobs +// M_I(359, 1, 2)------------- Use imitater ice, taking effect at 359cs void M_I(Time time, int row, int col) { if (!_SimpleAvZInternal::is_night_time()) { - _SimpleAvZInternal::error("M_I", "M_I为夜间复制冰函数, 不可在白昼使用"); + _SimpleAvZInternal::error("M_I", "M_I is for nighttime only"); } _SimpleAvZInternal::validate_card_position(M_ICE_SHROOM, row, col, "M_I"); @@ -340,31 +341,31 @@ void M_I(int row, int col) M_I(601, row, col); } -// 用卡. 可提供单一坐标, 多行同列, 或多卡同坐标. -// *** 使用示例: -// C(359, CHERRY, 2, 9)-------------------于2-9放置樱桃, 359cs生效 -// C(400, {PUFF, SUN}, {1, 2}, 9)---------于1-9放置小喷, 2-9放置阳光菇 -// C(359, {LILY, DOOM, COFFEE}, 3, 9)-----于3-9放置荷叶, 核武, 咖啡豆 +// Use cards. You may provide a single position, multiple rows with the same column, or multiple cards at the same position. +// *** Usage: +// C(359, CHERRY, 2, 9)------------------- Place cherry at 2-9, taking effect at 359cs +// C(400, {PUFF, SUN}, {1, 2}, 9)--------- Place puff-shroom at 1-9 and sun-shroom at 2-9 +// C(359, {LILY, DOOM, COFFEE}, 3, 9)----- Place lily pad, doom, and coffee bean at 3-9 // -// *** 生效时间的变种: -// C(after(110), ...)-----------用法同上, 延迟110cs生效 -// C(exact(800), ...)-----------不使用炮等效时间, 800cs生效 -// C(after(exact(..)), ...)-----以上两者的结合 +// *** Alternative forms of card time: +// C(after(110), ...)----------- Same usage, taking effect after 110cs +// C(exact(800), ...)----------- Use card-based time instead of cob-based time, taking effect at 800cs +// C(after(exact(..)), ...)----- Combination of the above two // -// *** 指定铲除时机: -// C(400, keep(266), ...)-------放置后266cs铲 -// C(400, until(1036), ...)-----1036cs铲 -// 注意: 容器会被一并铲除. +// *** Specify shovel time: +// C(400, keep(266), ...)------- Shovel 266cs after effect time +// C(400, until(1036), ...)----- Shovel at 1036cs +// Note: containers (lily pad, flower pot) will be shoveled as well. void C(Time time, ShovelTime shovel_time, const std::vector& plant_types, const std::vector& rows, int col) { if (plant_types.empty()) { - _SimpleAvZInternal::error("C", "要用的卡片不可为空"); + _SimpleAvZInternal::error("C", "Must provide the card to use"); } if (rows.empty()) { - _SimpleAvZInternal::error("C", "用卡行数不可为空"); + _SimpleAvZInternal::error("C", "Must provide which row to use the card"); } if (plant_types.size() != rows.size()) { - _SimpleAvZInternal::error("C", "卡片数与行数不一致\n卡片数: #\n行数: #", plant_types.size(), rows.size()); + _SimpleAvZInternal::error("C", "Number of cards and number of rows must be the same\nNumber of cards: #\nNumber of rows: #", plant_types.size(), rows.size()); } for (size_t i = 0; i < plant_types.size(); i++) { auto plant_type = plant_types.at(i); @@ -402,7 +403,7 @@ void C(Time time, const std::vector& plant_types, const std::vector& plant_types, int row, int col) { if (plant_types.empty()) { - _SimpleAvZInternal::error("C", "要用的卡片不可为空"); + _SimpleAvZInternal::error("C", "Must provide the card to use"); } for (const auto& plant_type : plant_types) { _SimpleAvZInternal::validate_card_position(plant_type, row, col, "C"); @@ -446,11 +447,11 @@ void C(Time time, PlantType plant_type, int row, int col) C(time, ShovelTime(), {{plant_type}}, {{row}}, col); } -// 智能用卡. 根据本行僵尸情况决定是否用卡. -// 提供"僵尸是否存在", 以及"僵尸x是否小于某值"两种判断方式. -// *** 使用示例: -// C_IF(exist(ZOMBONI), 400, SPIKEWEED, 1, 9)-------若本行存在冰车, 于400cs在1-9放置地刺 -// C_IF(pos({GARG, GIGA}, 680), 400, POT, 1, 8)-----若本行存在int(x)≤680的白眼或红眼, 于400cs在1-8放置花盆 +// Decide whether or not to use cards depending on zombies. +// You may either check if a certain type of zombie exists, or check if certain types of zombie's x is smaller than some threshold. +// *** Usage: +// C_IF(exist(ZOMBONI), 400, SPIKEWEED, 1, 9)------- If there is zomboni in row 1, place spikeweed at 1-9 at 400cs +// C_IF(pos({GARG, GIGA}, 680), 400, POT, 1, 8)----- If there is garg or giga with int(x)≤680, place flower pot at 1-8 at 400cs void C_IF(const std::function& condition, Time time, ShovelTime shovel_time, const PlantType& plant_type, int row, int col) { _SimpleAvZInternal::validate_card_position(plant_type, row, col, "C"); diff --git a/crescendo/SimpleAvZ/SimpleAvZ/error.h b/crescendo/SimpleAvZ/SimpleAvZ/error.h index 564b51d..0db196e 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/error.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/error.h @@ -8,7 +8,7 @@ template void error(const std::string& func_name, const std::string& content, Args... args) { AvZ::SetErrorMode(AvZ::POP_WINDOW); - AvZ::ShowErrorNotInQueue("[调用 " + func_name + " 时出错]\n" + content, args...); + AvZ::ShowErrorNotInQueue("[Error when calling " + func_name + " ]\n" + content, args...); throw ""; } diff --git a/crescendo/SimpleAvZ/SimpleAvZ/global.h b/crescendo/SimpleAvZ/SimpleAvZ/global.h index 772315c..b5c5b8c 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/global.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/global.h @@ -43,7 +43,7 @@ class Global : AvZ::GlobalVar { Global global; -// scene 相关 +// scene related bool is_night_time() { auto scene = AvZ::GetMainObject()->scene(); diff --git a/crescendo/SimpleAvZ/SimpleAvZ/ice_filler.h b/crescendo/SimpleAvZ/SimpleAvZ/ice_filler.h index 33c0556..6216488 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/ice_filler.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/ice_filler.h @@ -15,10 +15,10 @@ void set_ice_internal(const std::vector& ice_positions) auto row = pos.row; auto col = pos.col; if (row < 1 || row > max_row) { - _SimpleAvZInternal::error("SetIce", "存冰行数应在1~#内\n存冰行数: #", max_row, row); + _SimpleAvZInternal::error("SetIce", "Ice row should be within 1~#: #", max_row, row); } if (col < 1 || col > 9) { - _SimpleAvZInternal::error("SetIce", "存冰列数应在1~9内\n存冰列数: #", col); + _SimpleAvZInternal::error("SetIce", "Ice col should be within 1~9: #", col); } } @@ -32,11 +32,11 @@ void set_ice_internal(const std::vector& ice_positions) } // namespace _SimpleAvZInternal -// 设置存冰位置. -// 若不指定生效时间, 默认在 wave 1, -599cs 生效. -// *** 使用示例: -// SetIce({{1, 1}, {1, 2}})-----在1-1, 1-2存冰(优先使用1-2)[外] -// SetIce(400, {...})-----------400cs生效 +// Set where to store ices in daytime. +// If effect time is not specified, it defaults to game start (wave 1, -599cs). +// *** Usage: +// SetIce({{1, 1}, {1, 2}})----- Store and use ices at 1-1, 1-2 (use 1-2 first), effective since game start [EXT] +// SetIce(400, {...})----------- Effective since 400cs void SetIce(Time time, const std::vector& ice_positions) { _SimpleAvZInternal::get_effect_time_and_set_time(time, "SetIce"); @@ -49,16 +49,16 @@ void SetIce(const std::vector& ice_positions) _SimpleAvZInternal::set_ice_internal(ice_positions); } -// 白昼点冰. 自带生效时机修正. -// 若不指定生效时间, 默认在本波 601cs 生效. -// *** 使用示例: -// I()---------------点冰, 601cs生效(完美预判冰) -// I(after(210))-----延迟210cs生效(ice3), 推荐在激活炮后使用 -// I(359)------------359cs生效 +// Use ice in daytime. Effect time is auto-corrected. +// If effect time is not specified, it defaults to 601cs of the current wave (perfect ice for next wave). +// *** Usage: +// I()--------------- Use ice, taking effect at 601cs (perfect ice) +// I(after(210))----- Use ice, takeing effect after 210cs (ice3), recommended to be used after activation cobs +// I(359)------------ Use ice, taking effect at 359cs void I(Time time = Time(601)) { if (_SimpleAvZInternal::is_night_time()) { - _SimpleAvZInternal::error("I", "不可在夜间使用白昼版本的I()\n请提供用冰位置"); + _SimpleAvZInternal::error("I", "Cannot use daytime version of I() at nighttime\nPlease provide ice position"); } auto effect_time = _SimpleAvZInternal::get_card_effect_time(time, {ICE_SHROOM, COFFEE_BEAN}, "I"); diff --git a/crescendo/SimpleAvZ/SimpleAvZ/iterator.h b/crescendo/SimpleAvZ/SimpleAvZ/iterator.h index be022d1..59b2401 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/iterator.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/iterator.h @@ -31,7 +31,7 @@ class WavesValidator : AvZ::GlobalVar { } } if (!duplicate_waves.empty()) { - error("waves", "waves调用的波次不可重复.\n重复的波次: " + concat(duplicate_waves, ",")); + error("waves", "duplicate wave in waves(): " + concat(duplicate_waves, ",")); } } }; @@ -45,7 +45,7 @@ class Wave { : value(v) { } - + operator int() const { return value; @@ -108,12 +108,12 @@ class Waves { std::vector wave_range_to_waves_vec(const std::array& wave_range, int step, const std::string& func_name) { if (wave_range[0] > wave_range[1]) { - _SimpleAvZInternal::error(func_name, "起始波数应≤终止波数\n起始波数: #\n终止波数: #", wave_range[0], wave_range[1]); + _SimpleAvZInternal::error(func_name, "Start wave should ≤ end wave\nStart wave: #\nEnd wave: #", wave_range[0], wave_range[1]); } std::vector<_SimpleAvZInternal::Wave> waves_vec; for (int w = wave_range[0]; w <= wave_range[1]; w += step) { if (w < 1 || w > 20) { - _SimpleAvZInternal::error(func_name, "波数应在1~20内\n当前为: #", w); + _SimpleAvZInternal::error(func_name, "Wave should be within 1~20: #", w); } _SimpleAvZInternal::waves_validator.waves.push_back(w); waves_vec.push_back( @@ -124,21 +124,21 @@ std::vector wave_range_to_waves_vec(const std::array& wave_range, } -// 设定波次. -// 基础用法: for (auto w : waves(...)) { -// // 具体操作 -// } -// *** 使用例: -// waves(1, 2, 3)-----------------w1, w2, w3(可指定任意多个) -// waves({1, 9}, 4)---------------w1-w9 每4波一循环 -// waves({1, 9}, {11, 19}, 4)-----w1-w9, w11-w19 每4波一循环 +// Set wave. +// Basic usage: for (auto w : waves(...)) { +// // here goes your operations... +// } +// *** Usage: +// waves(1, 2, 3)----------------- w1, w2, w3 (may specify any number of waves) +// waves({1, 9}, 4)--------------- from w1 to w9, every 4 waves +// waves({1, 9}, {11, 19}, 4)----- from w1 to w9 and from w11 to w19, every 4 waves template _SimpleAvZInternal::Waves waves(Args... args) { std::vector<_SimpleAvZInternal::Wave> waves_vec = {_SimpleAvZInternal::Wave(args)...}; for (const auto& w : waves_vec) { if (w.value < 1 || w.value > 20) { - _SimpleAvZInternal::error("waves", "波数应在1~20内\n波数: #", w.value); + _SimpleAvZInternal::error("waves", "Wave should be within 1~20: #", w.value); } _SimpleAvZInternal::waves_validator.waves.push_back(w.value); } @@ -148,7 +148,7 @@ _SimpleAvZInternal::Waves waves(Args... args) _SimpleAvZInternal::Waves waves(const std::array& wave_range_1, const std::array& wave_range_2, int step) { if (step <= 0) { - _SimpleAvZInternal::error("waves", "循环长度应>0\n循环长度: #", step); + _SimpleAvZInternal::error("waves", "Step should >0: #", step); } auto waves_vec_1 = _SimpleAvZInternal::wave_range_to_waves_vec(wave_range_1, step, "waves"); @@ -160,7 +160,7 @@ _SimpleAvZInternal::Waves waves(const std::array& wave_range_1, const st _SimpleAvZInternal::Waves waves(const std::array& wave_range, int step) { if (step <= 0) { - _SimpleAvZInternal::error("waves", "循环长度应>0\n循环长度: #", step); + _SimpleAvZInternal::error("waves", "Step should >0: #", step); } return _SimpleAvZInternal::Waves(_SimpleAvZInternal::wave_range_to_waves_vec(wave_range, step, "waves")); diff --git a/crescendo/SimpleAvZ/SimpleAvZ/time.h b/crescendo/SimpleAvZ/SimpleAvZ/time.h index f25b5a3..c827e3c 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/time.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/time.h @@ -80,7 +80,7 @@ namespace _SimpleAvZInternal { int get_delayed_time_and_update(int delay_time, const std::string& func_name) { if (!global.is_last_effect_time_initialized()) { - error(func_name + "-->after", "没有延迟的基准, 请先使用固定时间的用炮/用卡函数"); + error(func_name + "-->after", "There is no time base for delay. Please use functions with fixed time first."); } global.last_effect_time += delay_time; @@ -92,7 +92,7 @@ int get_delayed_time_and_update(int delay_time, const std::string& func_name) int get_effect_time(Time time, const std::string& func_name) { if (!global.is_last_effect_wave_initialized()) { - error(func_name, "没有设置波数, 请用以下方式调用本函数:\nfor (auto w : waves(...)){\n // 调用本函数\n}"); + error(func_name, "You haven't set wave yet. Please use this function as such:\nfor (auto w : waves(...)){\n // this function\n}"); } switch (time.type) { @@ -110,7 +110,7 @@ int get_effect_time(Time time, const std::string& func_name) void set_time_inside(int time, const std::string& func_name) { if (!global.is_last_effect_wave_initialized()) { - error(func_name, "没有设置波数, 请用以下方式调用本函数:\nfor (auto w : waves(...)){\n // 调用本函数\n}"); + error(func_name, "You haven't set wave yet. Please use this function as such:\nfor (auto w : waves(...)){\n // this function\n}"); } AvZ::SetTime(time, global.last_effect_wave); } @@ -124,7 +124,7 @@ void get_effect_time_and_set_time(Time time, const std::string& func_name) void set_time_outside(int time, int wave, const std::string& func_name) { if (global.is_last_effect_wave_initialized()) { - error(func_name, "若省略生效时间, 需在waves()循环节外使用"); + error(func_name, "If time is omitted, you must use this function outside waves() loops."); } AvZ::SetTime(time, wave); diff --git a/crescendo/SimpleAvZ/SimpleAvZ/zombie.h b/crescendo/SimpleAvZ/SimpleAvZ/zombie.h index c607f41..340d4c6 100644 --- a/crescendo/SimpleAvZ/SimpleAvZ/zombie.h +++ b/crescendo/SimpleAvZ/SimpleAvZ/zombie.h @@ -33,44 +33,44 @@ struct EnsureExistInfo { void validate() const { if (INVALID_ZOMBIES.count(zombie_type)) { - error("EnsureExist", "不支持的僵尸类型: #", zombie_type); + error("EnsureExist", "Unsupported zombie type: #", zombie_type); } for (const auto& row : rows) { if (row < 1 || row > get_max_spawn_row()) { - error("EnsureExist", "僵尸行数应在1~#内\n无效的行数: #", get_max_spawn_row(), row); + error("EnsureExist", "Zombie row should be within 1~#: #", get_max_spawn_row(), row); } } - auto detail_str = "僵尸类型: " + std::to_string(static_cast(zombie_type)) + "\n僵尸所在行: " + concat(rows, ","); + auto detail_str = "Zombie type: " + std::to_string(static_cast(zombie_type)) + "\nZombie rows: " + concat(rows, ","); if (has_water_rows()) { if (AQUATIC_ZOMBIES.count(zombie_type)) { if (AvZ::GetMainObject()->scene() == 8) { - error("EnsureExist", "水族馆不出潜水与海豚\n" + detail_str); + error("EnsureExist", "Cannot spawn snorkel or dolphin in aquarium scene\n" + detail_str); } else if (rows.count(3) + rows.count(4) != rows.size()) { - error("EnsureExist", "非水路不出潜水与海豚\n" + detail_str); + error("EnsureExist", "Cannot spawn snorkel or dolphin in non-water rows\n" + detail_str); } } else if (zombie_type != BALLOON_ZOMBIE) { - if (rows.count(3) || rows.count(4)) { - error("EnsureExist", "暂不支持在水路设定潜水、海豚、气球以外的僵尸\n" + detail_str); + if ((rows.count(3) || rows.count(4))) { + error("EnsureExist", "Setting zombies except snorkel, dolphin, or balloon in water rows is not supported yet\n" + detail_str); } } } else { if (AQUATIC_ZOMBIES.count(zombie_type)) { - error("EnsureExist", "非后院不出潜水与海豚\n" + detail_str); + error("EnsureExist", "Cannot spawn snorkel or dolphin in non-backyard scenes\n" + detail_str); } if (no_dancing_in_side_rows() && zombie_type == DANCING_ZOMBIE && (rows.count(1) || rows.count(get_max_spawn_row()))) { - error("EnsureExist", "边路不出舞王\n" + detail_str); + error("EnsureExist", "Cannot spawn dancer in row 1 or 5\n" + detail_str); } if (no_zomboni() && zombie_type == ZOMBONI) { - error("EnsureExist", "黑夜不出冰车\n" + detail_str); + error("EnsureExist", "Cannot spawn zomboni in night scene\n" + detail_str); } if (is_roof() && (zombie_type == DANCING_ZOMBIE || zombie_type == DIGGER_ZOMBIE)) { - error("EnsureExist", "屋顶不出舞王与矿工\n" + detail_str); + error("EnsureExist", "Cannot spawn dancer or digger in roof scenes\n" + detail_str); } } } @@ -117,11 +117,12 @@ void move_zombie_row(Zombie* zombie, int target_row) } // namespace _SimpleAvZInternal -// 确保本波某类僵尸出现在某行. 需在waves()循环节内使用. 对本波有效. -// *** 使用示例: -// EnsureExist(GIGA)-----------------------------确保红眼出现在所有合理行 -// EnsureExist({GIGA, 2, 3})---------------------确保红眼出现在第2,3行 -// EnsureExist({{GIGA, 2, 3}, {ZOMBONI, 4}})-----确保红眼出现在第2,3行, 冰车出现在第4行 +// Ensure some zombies appear in certain rows for the current wave. +// Must be used within waves() loops. +// *** Usage: +// EnsureExist(GIGA)----------------------------- Ensure giga appears in all reasonable rows +// EnsureExist({GIGA, 2, 3})--------------------- Ensure giga appears in row 2 & 3 +// EnsureExist({{GIGA, 2, 3}, {ZOMBONI, 4}})----- Ensure giga appears in row 2 & 3 and zomboni appears in row 4 void EnsureExist(const std::vector<_SimpleAvZInternal::EnsureExistInfo>& ensure_exist_info_list) { std::set seen_zombie_types; @@ -129,7 +130,7 @@ void EnsureExist(const std::vector<_SimpleAvZInternal::EnsureExistInfo>& ensure_ info.validate(); if (seen_zombie_types.count(info.zombie_type)) { - _SimpleAvZInternal::error("EnsureExist", "僵尸类型重复: #", info.zombie_type); + _SimpleAvZInternal::error("EnsureExist", "Duplicate zombie type: #", info.zombie_type); } seen_zombie_types.insert(info.zombie_type); } @@ -178,7 +179,7 @@ void EnsureExist(const std::vector<_SimpleAvZInternal::EnsureExistInfo>& ensure_ best_src_row = row; } if (zombie_index[zombie_type][best_src_row].size() <= 1) { - AvZ::ShowErrorNotInQueue("僵尸数量不足, 无法确保种类为 # 的僵尸出现在 # 行", zombie_type, target_row); + AvZ::ShowErrorNotInQueue("Not enough zombies of type # to ensure it appears in row #", zombie_type, target_row); continue; } }