diff --git a/docs/战斗流程协议.md b/docs/战斗流程协议.md index 88ba8d4a37..75b8e21c39 100644 --- a/docs/战斗流程协议.md +++ b/docs/战斗流程协议.md @@ -42,44 +42,47 @@ ], "actions": [ // 战斗中的操作。有序,执行完前一个才会去执行下一个。必选 { - "type": 0, // 操作类型,可选,默认 0 - // 0 - 部署; 1 - 撤退; 2 - 开技能; - // 100 - 切换二倍速开关;101 - 切换 1/5 速度(点击任意干员) - // 若为 0, 当费用不够时,会一直等待到费用够(除非 timeout) - // 若为 2, 当技能 cd 没转好时,一直等待到技能 cd 好(除非 timeout) + "type": "Deploy", // 操作类型,可选,默认 "Deploy" + // "Deploy" | "Skill" | "Retreat" | "SpeedUp" | "BulletTime" + // "部署" | "技能" | "撤退" | "二倍速" | "子弹时间" + // 中英文皆可,效果相同 + // 若为 "部署", 当费用不够时,会一直等待到费用够(除非 timeout) + // 若为 "技能", 当技能 cd 没转好时,一直等待到技能 cd 好(除非 timeout) + // "二倍速" 是可切换的,即使用一次变成二倍速,再次使用又变回一倍速 + // "子弹时间" 即点击任意干员后的 1/5 速度,再进行任意 action 会恢复正常速度 - "kills": 0, // 击杀数条件,如果没达到就一直等待,可选,默认为空。直接执行 + "kills": 0, // 击杀数条件,如果没达到就一直等待。可选,默认为 0。直接执行 // TODO: 其他条件 // TODO: "condition_type": 0, // 执行条件间的关系,可选,默认 0 // // 0 - 且; 1 - 或 - "name": "棘刺", // 干员名 或 群组名,action < 100 时必选 + "name": "棘刺", // 干员名 或 群组名, type 为 "部署" | "技能" | "撤退" 之一时必选 - "location": [ 5, 5 ], // 部署干员的位置。action == 0 时必选 + "location": [ 5, 5 ], // 部署干员的位置。 type 为 "部署" 时必选 - "direction": 0, // 部署干员的干员朝向。action == 0 时必选 - // 0 - 右; 1 - 下; 2 - 左; 3 - 上 - // 4 - 无朝向(适用于召唤物) + "direction": "Left", // 部署干员的干员朝向。 type 为 "部署" 时必选 + // "Left" | "Right" | "Up" | "Down" | "None" + // "左" | "右" | "上" | "下" | "无" + // 中英文皆可,效果相同 "pre_delay": 0, // 前置延时。可选,默认 0, 单位毫秒 "rear_delay": 0, // 后置延时。可选,默认 0, 单位毫秒 - "timeout": 999999999 // 超时时间。可选,默认 INT_MAX, 单位毫秒 - // 当 type == 0 或 type == 1 且等待超时 - // 则放弃当前动作, 转而执行下一个动作 + "timeout": 999999999 // 超时时间。当 type 为 "部署" | "技能" 时可选。默认 INT_MAX, 单位毫秒 + // 等待超时则放弃当前动作, 转而执行下一个动作 }, // 举例 1 { "name": "任意正常群奶", "location": [ 5, 6 ], - "direction": 1 + "direction": "右" }, // 举例 2 { - "type": 100 + "type": "二倍速" } ], - "minimum_required": "v4.0", // 最低要求 maa 版本号,必选。保留字段 + "minimum_required": "v4.0", // 最低要求 maa 版本号,必选。保留字段 "desc": { // 描述,可选,保留字段。 // 后期完成了作业分享平台后,可能直接展示该字段给其他用户看 "title": "低练度高成功率作业", diff --git a/resource/battle/test.json b/resource/battle/test.json index 2c127d1649..e55028b7a0 100644 --- a/resource/battle/test.json +++ b/resource/battle/test.json @@ -27,7 +27,7 @@ 8, 4 ], - "direction": 2 + "direction": "左" }, { "name": "能天使", @@ -35,7 +35,7 @@ 8, 5 ], - "direction": 2 + "direction": "左" }, { "name": "澄闪", @@ -43,10 +43,10 @@ 7, 3 ], - "direction": 1 + "direction": "下" }, { - "type": 100 + "type": "二倍速" }, { "name": "临光", @@ -54,16 +54,16 @@ 7, 4 ], - "direction": 2 + "direction": "左" }, { "kills": 25, - "type": 2, + "type": "技能", "name": "澄闪" }, { "kills": 30, - "type": 1, + "type": "撤退", "name": "嵯峨" } ] diff --git a/src/MeoAssistant/AsstBattleDef.h b/src/MeoAssistant/AsstBattleDef.h index 8768952f43..1d88e3706f 100644 --- a/src/MeoAssistant/AsstBattleDef.h +++ b/src/MeoAssistant/AsstBattleDef.h @@ -10,79 +10,79 @@ namespace asst { - enum class BattleSkillUsage // 干员技能使用方法 - { - Possibly = 0, // 有就用,例如干员 棘刺 3 技能 - Once = 1, // 只用一次,例如干员 银灰 2技能 - InTime = 2, // 关键时刻使用,自动判断使用时机,例如干员 假日威龙陈 3 技能 - NotUse = 3, // 不自动使用 - OnceUsed - }; - struct BattleDeployOper // 干员 - { - std::string name; - int skill = 1; // 技能序号,取值范围 [1, 3] - BattleSkillUsage skill_usage = BattleSkillUsage::Possibly; - }; + enum class BattleSkillUsage // 干员技能使用方法 + { + Possibly = 0, // 有就用,例如干员 棘刺 3 技能 + Once = 1, // 只用一次,例如干员 银灰 2技能 + InTime = 2, // 关键时刻使用,自动判断使用时机,例如干员 假日威龙陈 3 技能 + NotUse = 3, // 不自动使用 + OnceUsed + }; + struct BattleDeployOper // 干员 + { + std::string name; + int skill = 1; // 技能序号,取值范围 [1, 3] + BattleSkillUsage skill_usage = BattleSkillUsage::Possibly; + }; - enum class BattleDeployDirection - { - Right = 0, - Down = 1, - Left = 2, - Up = 3, - No = 4 // 没有方向,通常是无人机之类的 - }; + enum class BattleDeployDirection + { + Right = 0, + Down = 1, + Left = 2, + Up = 3, + None = 4 // 没有方向,通常是无人机之类的 + }; - enum class BattleActionType // 操作类型 - { - Deploy = 0, // 部署干员 - Retreat = 1, // 撤退干员 - UseSkill = 2, // 开技能 - SwitchSpeed = 100, // 切换二倍速 - SlowMode = 101 // 使用 1/5 的速度(点击任意干员),会在下一个任意操作后恢复原速度 - }; + enum class BattleActionType // 操作类型 + { + Deploy = 0, // 部署干员 + UseSkill = 1, // 开技能 + Retreat = 2, // 撤退干员 + SwitchSpeed = 100, // 切换二倍速 + BulletTime = 101 // 使用 1/5 的速度(点击任意干员),会在下一个任意操作后恢复原速度 + }; - struct BattleAction // 操作 - { - int kills = 0; - BattleActionType type = BattleActionType::Deploy; - std::string group_name; // 目标名,若 type >= SwitchSpeed, group_name 为空 - Point location; - BattleDeployDirection direction = BattleDeployDirection::Right; - int pre_delay = 0; - int rear_delay = 0; - int time_out = INT_MAX; - }; + struct BattleAction // 操作 + { + int kills = 0; + BattleActionType type = BattleActionType::Deploy; + std::string group_name; // 目标名,若 type >= SwitchSpeed, group_name 为空 + Point location; + BattleDeployDirection direction = BattleDeployDirection::Right; + int pre_delay = 0; + int rear_delay = 0; + int time_out = INT_MAX; + }; - struct BattleActionsGroup - { - std::unordered_map> opers_groups; - std::vector actions; - }; + struct BattleActionsGroup + { + std::unordered_map> opers_groups; + std::vector actions; + }; - enum class BattleRole - { - Unknown, - Caster, - Medic, - Pioneer, - Sniper, - Special, - Support, - Tank, - Warrior, - Drone - }; + enum class BattleRole + { + Unknown, + Caster, + Medic, + Pioneer, + Sniper, + Special, + Support, + Tank, + Warrior, + Drone + }; - struct BattleRealTimeOper - { - int cost = 0; - BattleRole role = BattleRole::Unknown; - bool available = false; - Rect rect; - cv::Mat avatar; - std::string name; - size_t index; - }; + struct BattleRealTimeOper + { + int cost = 0; + BattleRole role = BattleRole::Unknown; + bool available = false; + Rect rect; + cv::Mat avatar; + std::string name; + size_t index; + }; } diff --git a/src/MeoAssistant/BattleConfiger.cpp b/src/MeoAssistant/BattleConfiger.cpp index 515b5e0e45..6f5183b527 100644 --- a/src/MeoAssistant/BattleConfiger.cpp +++ b/src/MeoAssistant/BattleConfiger.cpp @@ -6,57 +6,130 @@ bool asst::BattleConfiger::parse(const json::value& json) { - std::string stage_name = json.at("stage_name").as_string(); + std::string stage_name = json.at("stage_name").as_string(); - BattleActionsGroup battle_actions; + BattleActionsGroup battle_actions; - if (json.contains("opers_groups")) { - for (const auto& group_info : json.at("opers_groups").as_array()) { - std::string group_name = group_info.at("name").as_string(); - std::vector oper_vec; - for (const auto& oper_info : group_info.at("opers").as_array()) { - BattleDeployOper oper; - oper.name = oper_info.at("name").as_string(); - oper.skill = oper_info.get("skill", 1); - oper.skill_usage = static_cast(oper_info.get("skill_usage", 0)); - oper_vec.emplace_back(std::move(oper)); - } - battle_actions.opers_groups.emplace(std::move(group_name), std::move(oper_vec)); - } - } + if (json.contains("opers_groups")) { + for (const auto& group_info : json.at("opers_groups").as_array()) { + std::string group_name = group_info.at("name").as_string(); + std::vector oper_vec; + for (const auto& oper_info : group_info.at("opers").as_array()) { + BattleDeployOper oper; + oper.name = oper_info.at("name").as_string(); + oper.skill = oper_info.get("skill", 1); + oper.skill_usage = static_cast(oper_info.get("skill_usage", 0)); + oper_vec.emplace_back(std::move(oper)); + } + battle_actions.opers_groups.emplace(std::move(group_name), std::move(oper_vec)); + } + } - if (json.contains("opers")) { - for (const auto& oper_info : json.at("opers").as_array()) { - BattleDeployOper oper; - oper.name = oper_info.at("name").as_string(); - oper.skill = oper_info.get("skill", 1); - oper.skill_usage = static_cast(oper_info.get("skill_usage", 0)); + if (json.contains("opers")) { + for (const auto& oper_info : json.at("opers").as_array()) { + BattleDeployOper oper; + oper.name = oper_info.at("name").as_string(); + oper.skill = oper_info.get("skill", 1); + oper.skill_usage = static_cast(oper_info.get("skill_usage", 0)); - // 单个干员的,干员名直接作为组名 - std::string group_name = oper.name; + // 单个干员的,干员名直接作为组名 + std::string group_name = oper.name; - battle_actions.opers_groups.emplace(std::move(group_name), std::vector{ std::move(oper) }); - } - } + battle_actions.opers_groups.emplace(std::move(group_name), std::vector{ std::move(oper) }); + } + } - for (const auto& action_info : json.at("actions").as_array()) { - BattleAction action; - action.type = static_cast(action_info.get("type", 0)); - action.kills = action_info.get("kills", 0); - action.group_name = action_info.get("name", std::string()); + for (const auto& action_info : json.at("actions").as_array()) { + BattleAction action; + static const std::unordered_map ActionTypeMapping = { + { "Deploy", BattleActionType::Deploy }, + { "DEPLOY", BattleActionType::Deploy }, + { "deploy", BattleActionType::Deploy }, + { "部署", BattleActionType::Deploy }, - action.location.x = action_info.get("location", 0, 0); - action.location.y = action_info.get("location", 1, 0); + { "Skill", BattleActionType::UseSkill }, + { "SKILL", BattleActionType::UseSkill }, + { "skill", BattleActionType::UseSkill }, + { "技能", BattleActionType::UseSkill }, - action.direction = static_cast(action_info.get("direction", 0)); - action.pre_delay = action_info.get("pre_delay", 0); - action.rear_delay = action_info.get("rear_delay", 0); - action.time_out = action_info.get("timeout", INT_MAX); + { "Retreat", BattleActionType::Retreat }, + { "RETREAT", BattleActionType::Retreat }, + { "retreat", BattleActionType::Retreat }, + { "撤退", BattleActionType::Retreat }, - battle_actions.actions.emplace_back(std::move(action)); - } + { "SpeedUp", BattleActionType::SwitchSpeed }, + { "SPEEDUP", BattleActionType::SwitchSpeed }, + { "Speedup", BattleActionType::SwitchSpeed }, + { "speedup", BattleActionType::SwitchSpeed }, + { "二倍速", BattleActionType::SwitchSpeed }, - m_battle_actions[std::move(stage_name)] = std::move(battle_actions); + { "BulletTime", BattleActionType::SwitchSpeed }, + { "BULLETTIME", BattleActionType::SwitchSpeed }, + { "Bullettime", BattleActionType::SwitchSpeed }, + { "bullettime", BattleActionType::SwitchSpeed }, + { "子弹时间", BattleActionType::SwitchSpeed }, + }; - return true; -} \ No newline at end of file + std::string type_str = action_info.get("type", "Deploy"); + + if (auto iter = ActionTypeMapping.find(type_str); + iter != ActionTypeMapping.end()) { + action.type = iter->second; + } + else { + action.type = BattleActionType::Deploy; + } + action.kills = action_info.get("kills", 0); + action.group_name = action_info.get("name", std::string()); + + action.location.x = action_info.get("location", 0, 0); + action.location.y = action_info.get("location", 1, 0); + + static const std::unordered_map DeployDirectionMapping = { + { "Right", BattleDeployDirection::Right }, + { "RIGHT", BattleDeployDirection::Right }, + { "right", BattleDeployDirection::Right }, + { "右", BattleDeployDirection::Right }, + + { "Left", BattleDeployDirection::Left }, + { "LEFT", BattleDeployDirection::Left }, + { "left", BattleDeployDirection::Left }, + { "左", BattleDeployDirection::Left }, + + { "Up", BattleDeployDirection::Up }, + { "UP", BattleDeployDirection::Up }, + { "up", BattleDeployDirection::Up }, + { "上", BattleDeployDirection::Up }, + + { "Down", BattleDeployDirection::Down }, + { "DOWN", BattleDeployDirection::Down }, + { "down", BattleDeployDirection::Down }, + { "下", BattleDeployDirection::Down }, + + { "None", BattleDeployDirection::None }, + { "NONE", BattleDeployDirection::None }, + { "none", BattleDeployDirection::None }, + { "无", BattleDeployDirection::None }, + }; + + std::string direction_str = action_info.get("direction", "Right"); + + if (auto iter = DeployDirectionMapping.find(direction_str); + iter != DeployDirectionMapping.end()) { + action.direction = iter->second; + } + else { + action.direction = BattleDeployDirection::Right; + } + + action.pre_delay = action_info.get("pre_delay", 0); + action.rear_delay = action_info.get("rear_delay", 0); + action.time_out = action_info.get("timeout", INT_MAX); + + battle_actions.actions.emplace_back(std::move(action)); + } + + m_battle_actions[std::move(stage_name)] = std::move(battle_actions); + + return true; +} diff --git a/src/MeoAssistant/BattleProcessTask.cpp b/src/MeoAssistant/BattleProcessTask.cpp index 72790d5ce7..a1d0a03cef 100644 --- a/src/MeoAssistant/BattleProcessTask.cpp +++ b/src/MeoAssistant/BattleProcessTask.cpp @@ -194,7 +194,7 @@ bool asst::BattleProcessTask::do_action(const BattleAction& action) case BattleActionType::SwitchSpeed: return battle_speedup(); break; - case BattleActionType::SlowMode: + case BattleActionType::BulletTime: break; } @@ -251,13 +251,13 @@ bool asst::BattleProcessTask::oper_deploy(const BattleAction& action) sleep(use_oper_task_ptr->rear_delay); // 拖动干员朝向 - if (action.direction != BattleDeployDirection::No) { + if (action.direction != BattleDeployDirection::None) { static const std::unordered_map DirectionMapping = { { BattleDeployDirection::Right, Point(1, 0)}, { BattleDeployDirection::Down, Point(0, 1)}, { BattleDeployDirection::Left, Point(-1, 0)}, { BattleDeployDirection::Up, Point(0, -1)}, - { BattleDeployDirection::No, Point(0, 0)}, + { BattleDeployDirection::None, Point(0, 0)}, }; // 计算往哪边拖动