chore.修改自动战斗部分字段支持中文

This commit is contained in:
MistEO
2022-03-22 23:33:15 +08:00
parent 619285e6d5
commit e020d11770
5 changed files with 215 additions and 139 deletions

View File

@@ -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": "低练度高成功率作业",

View File

@@ -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": "嵯峨"
}
]

View File

@@ -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<std::string, std::vector<BattleDeployOper>> opers_groups;
std::vector<BattleAction> actions;
};
struct BattleActionsGroup
{
std::unordered_map<std::string, std::vector<BattleDeployOper>> opers_groups;
std::vector<BattleAction> 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;
};
}

View File

@@ -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<BattleDeployOper> 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<BattleSkillUsage>(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<BattleDeployOper> 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<BattleSkillUsage>(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<BattleSkillUsage>(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<BattleSkillUsage>(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<BattleActionType>(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<std::string, BattleActionType> 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<BattleDeployDirection>(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;
}
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<std::string, BattleDeployDirection> 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;
}

View File

@@ -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<BattleDeployDirection, Point> 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)},
};
// 计算往哪边拖动