Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 67 additions & 18 deletions MeoAsstMac/Configuration Views/FightSettingsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,75 @@ struct FightSettingsView: View {
var body: some View {
Form {
Section {
HStack(spacing: 20) {
if useCustomStage || stageNotListed {
TextField("关卡名", text: $config.stage)
} else {
Picker("关卡选择", selection: $config.stage) {
Text("当前/上次").tag("")
Text("1-7").tag("1-7")
Text("CE-6").tag("CE-6")
Text("AP-5").tag("AP-5")
Text("CA-5").tag("CA-5")
Text("LS-6").tag("LS-6")
Text("剿灭模式").tag("Annihilation")
Toggle("使用备选关卡", isOn: $config.useOptionalStage)
.onChange(of: config.useOptionalStage) { enabled in
if enabled, config.stagePlan.count < 2 {
config.stagePlan = [config.stage, ""]
}
}
Toggle("手动输入关卡名", isOn: isUsingCustomStage)
}
.animation(.default, value: config.stage)
}

if useCustomStage || stageNotListed {
Text("<无忧梦呓>请使用特殊关卡名,如AveMujica-8").foregroundStyle(.secondary)
if config.useOptionalStage {
ForEach(config.stagePlan.indices, id: \.self) { index in
let stageName = config.stagePlan[index]
let isOpen = !stageName.isEmpty && FightConfiguration.isStageOpenToday(stageName)
HStack(spacing: 8) {
if planListedStages.contains(stageName) {
Picker("关卡 \(index + 1)", selection: $config.stagePlan[index]) {
Text("当前/上次").tag("")
Text("1-7").tag("1-7")
Text("CE-6").tag("CE-6")
Text("AP-5").tag("AP-5")
Text("CA-5").tag("CA-5")
Text("LS-6").tag("LS-6")
Text("SK-5").tag("SK-5")
Text("剿灭模式").tag("Annihilation")
}
} else {
TextField("关卡 \(index + 1)", text: $config.stagePlan[index])
}
if !stageName.isEmpty {
Image(systemName: isOpen ? "checkmark.circle.fill" : "clock.fill")
.foregroundColor(isOpen ? .green : .orange)
.help(isOpen ? "今天开放" : "今天不开放")
}
Button {
config.stagePlan.remove(at: index)
} label: {
Image(systemName: "minus.circle.fill").foregroundColor(.red)
}
.buttonStyle(.plain)
.disabled(config.stagePlan.count <= 1)
}
}
Button {
config.stagePlan.append("")
} label: {
Label("添加备选关卡", systemImage: "plus.circle")
}
Text("从上往下选择今天第一个开放的关卡执行").foregroundStyle(.secondary).font(.caption)
} else {
HStack(spacing: 20) {
if useCustomStage || stageNotListed {
TextField("关卡名", text: $config.stage)
} else {
Picker("关卡选择", selection: $config.stage) {
Text("当前/上次").tag("")
Text("1-7").tag("1-7")
Text("CE-6").tag("CE-6")
Text("AP-5").tag("AP-5")
Text("CA-5").tag("CA-5")
Text("LS-6").tag("LS-6")
Text("剿灭模式").tag("Annihilation")
}
}
Toggle("手动输入关卡名", isOn: isUsingCustomStage)
}
.animation(.default, value: config.stage)

if useCustomStage || stageNotListed {
Text("<无忧梦呓>请使用特殊关卡名,如AveMujica-8").foregroundStyle(.secondary)
}
}
}

Divider()
Expand Down Expand Up @@ -212,6 +260,7 @@ struct FightSettingsView: View {

private var stageNotListed: Bool { !listedStages.contains(config.stage) }
private let listedStages = ["", "1-7", "CE-6", "AP-5", "CA-5", "LS-6", "Annihilation"]
private let planListedStages: Set<String> = ["", "1-7", "CE-6", "AP-5", "CA-5", "LS-6", "SK-5", "Annihilation"]
}

struct FightSettingsView_Previews: PreviewProvider {
Expand Down
72 changes: 69 additions & 3 deletions MeoAsstMac/Task Configurations/FightConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ struct FightConfiguration: MAATaskConfiguration {
var type: MAATaskType { .Fight }

var stage: String
var stagePlan: [String]
var useOptionalStage: Bool

var medicine: Int?
var expiring_medicine: Int?
var stone: Int?
Expand All @@ -29,6 +32,10 @@ struct FightConfiguration: MAATaskConfiguration {
}

var subtitle: String {
if useOptionalStage {
let stages = stagePlan.filter { !$0.isEmpty }
return stages.isEmpty ? NSLocalizedString("当前/上次", comment: "") : stages.joined(separator: " / ")
}
if stage == "" {
return NSLocalizedString("当前/上次", comment: "")
} else {
Expand Down Expand Up @@ -58,10 +65,67 @@ struct FightConfiguration: MAATaskConfiguration {
.fight(self)
}

typealias Params = Self
// MARK: - Params sent to MAA Core

struct CoreParams: Encodable {
var stage: String
var medicine: Int?
var expiring_medicine: Int?
var stone: Int?
var times: Int?
var series: Int?
var drops: [String: Int]?
var report_to_penguin: Bool
var penguin_id: String
var server: String
var client_type: String
var DrGrandet: Bool
}

typealias Params = CoreParams

var params: CoreParams {
let activeStage: String
if useOptionalStage {
activeStage = stagePlan.first { Self.isStageOpenToday($0) } ?? stagePlan.first ?? ""
} else {
activeStage = stage
}
return CoreParams(
stage: activeStage,
medicine: medicine,
expiring_medicine: expiring_medicine,
stone: stone,
times: times,
series: series,
drops: drops,
report_to_penguin: report_to_penguin,
penguin_id: penguin_id,
server: server,
client_type: client_type,
DrGrandet: DrGrandet
)
}

var params: Self {
self
// MARK: - Stage Open Days
// Calendar.weekday: 1=Sun, 2=Mon, 3=Tue, 4=Wed, 5=Thu, 6=Fri, 7=Sat
private static let stageOpenDays: [String: Set<Int>] = [
"CE-6": [3, 5, 7, 1], // Tue, Thu, Sat, Sun
"AP-5": [2, 5, 7, 1], // Mon, Thu, Sat, Sun
"CA-5": [3, 4, 6, 1], // Tue, Wed, Fri, Sun
"SK-5": [2, 4, 6, 7], // Mon, Wed, Fri, Sat
"PR-A-1": [2, 5, 6, 1], "PR-A-2": [2, 5, 6, 1], // Mon, Thu, Fri, Sun
"PR-B-1": [2, 3, 6, 7], "PR-B-2": [2, 3, 6, 7], // Mon, Tue, Fri, Sat
"PR-C-1": [4, 5, 7, 1], "PR-C-2": [4, 5, 7, 1], // Wed, Thu, Sat, Sun
"PR-D-1": [3, 4, 7, 1], "PR-D-2": [3, 4, 7, 1], // Tue, Wed, Sat, Sun
]

/// 判断关卡今天是否开放(未在列表中的关卡视为全天开放)
static func isStageOpenToday(_ stage: String) -> Bool {
guard !stage.isEmpty else { return true }
guard let days = stageOpenDays[stage] else { return true }
let weekday = Calendar.current.component(.weekday, from: Date())
return days.contains(weekday)
}

// 掉落物品列表
Expand Down Expand Up @@ -130,6 +194,8 @@ extension FightConfiguration {
init(from decoder: any Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.stage = try container.decodeIfPresent(String.self, forKey: .stage) ?? ""
self.useOptionalStage = try container.decodeIfPresent(Bool.self, forKey: .useOptionalStage) ?? false
self.stagePlan = try container.decodeIfPresent([String].self, forKey: .stagePlan) ?? [self.stage]
self.medicine = try container.decodeIfPresent(Int.self, forKey: .medicine)
self.expiring_medicine = try container.decodeIfPresent(Int.self, forKey: .expiring_medicine)
self.stone = try container.decodeIfPresent(Int.self, forKey: .stone)
Expand Down
2 changes: 2 additions & 0 deletions MeoAsstMac/Task Configurations/LegacyConfigurations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ extension InfrastConfiguration {
extension FightConfiguration {
fileprivate init(migrating config: LegacyFightConfiguration) {
self.stage = config.stage
self.stagePlan = [config.stage]
self.useOptionalStage = false
self.medicine = config.medicine
self.expiring_medicine = config.expiring_medicine
self.stone = config.stone
Expand Down
21 changes: 21 additions & 0 deletions Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,9 @@
}
}
}
},
"SK-5" : {

},
"SSSGamePass" : {
"localizations" : {
Expand Down Expand Up @@ -1874,6 +1877,15 @@
}
}
}
},
"今天不开放" : {

},
"今天开放" : {

},
"从上往下选择今天第一个开放的关卡执行" : {

},
"从剪贴板读取" : {
"localizations" : {
Expand Down Expand Up @@ -1997,6 +2009,9 @@
}
}
}
},
"使用备选关卡" : {

},
"使用密文板" : {
"localizations" : {
Expand Down Expand Up @@ -2177,6 +2192,9 @@
}
}
}
},
"关卡 %lld" : {

},
"关卡名" : {
"localizations" : {
Expand Down Expand Up @@ -3808,6 +3826,9 @@
}
}
}
},
"添加备选关卡" : {

},
"游戏设置" : {
"localizations" : {
Expand Down