1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
package moe.nea.firmament.features.world
import com.mojang.brigadier.arguments.StringArgumentType
import kotlinx.serialization.serializer
import net.minecraft.text.Text
import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.commands.DefaultSource
import moe.nea.firmament.commands.RestArgumentType
import moe.nea.firmament.commands.get
import moe.nea.firmament.commands.suggestsList
import moe.nea.firmament.commands.thenArgument
import moe.nea.firmament.commands.thenExecute
import moe.nea.firmament.commands.thenLiteral
import moe.nea.firmament.events.CommandEvent
import moe.nea.firmament.util.ClipboardUtils
import moe.nea.firmament.util.FirmFormatters
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.TemplateUtil
import moe.nea.firmament.util.data.MultiFileDataHolder
import moe.nea.firmament.util.tr
object FirmWaypointManager {
object DataHolder : MultiFileDataHolder<FirmWaypoints>(serializer(), "waypoints")
val SHARE_PREFIX = "FIRM_WAYPOINTS/"
val ENCODED_SHARE_PREFIX = TemplateUtil.getPrefixComparisonSafeBase64Encoding(SHARE_PREFIX)
fun createExportableCopy(
waypoints: FirmWaypoints,
): FirmWaypoints {
val copy = waypoints.copy(waypoints = waypoints.waypoints.toMutableList())
if (waypoints.isRelativeTo != null) {
val origin = waypoints.lastRelativeImport
if (origin != null) {
copy.waypoints.replaceAll {
it.copy(
x = it.x - origin.x,
y = it.y - origin.y,
z = it.z - origin.z,
)
}
} else {
TODO("Add warning!")
}
}
return copy
}
fun loadWaypoints(waypoints: FirmWaypoints, sendFeedback: (Text) -> Unit) {
val copy = waypoints.deepCopy()
if (copy.isRelativeTo != null) {
val origin = MC.player!!.blockPos
copy.waypoints.replaceAll {
it.copy(
x = it.x + origin.x,
y = it.y + origin.y,
z = it.z + origin.z,
)
}
copy.lastRelativeImport = origin.toImmutable()
sendFeedback(tr("firmament.command.waypoint.import.ordered.success",
"Imported ${copy.size} relative waypoints. Make sure you stand in the correct spot while loading the waypoints: ${copy.isRelativeTo}."))
} else {
sendFeedback(tr("firmament.command.waypoint.import.success",
"Imported ${copy.size} waypoints."))
}
Waypoints.waypoints = copy
}
fun setOrigin(source: DefaultSource, text: String?) {
val waypoints = Waypoints.useEditableWaypoints()
waypoints.isRelativeTo = text ?: waypoints.isRelativeTo ?: ""
val pos = MC.player!!.blockPos
waypoints.lastRelativeImport = pos
source.sendFeedback(tr("firmament.command.waypoint.originset",
"Set the origin of waypoints to ${FirmFormatters.formatPosition(pos)}. Run /firm waypoints export to save the waypoints relative to this position."))
}
@Subscribe
fun onCommands(event: CommandEvent.SubCommand) {
event.subcommand(Waypoints.WAYPOINTS_SUBCOMMAND) {
thenLiteral("setorigin") {
thenExecute {
setOrigin(source, null)
}
thenArgument("hint", RestArgumentType) { text ->
thenExecute {
setOrigin(source, this[text])
}
}
}
thenLiteral("clearorigin") {
thenExecute {
val waypoints = Waypoints.useEditableWaypoints()
waypoints.lastRelativeImport = null
waypoints.isRelativeTo = null
source.sendFeedback(tr("firmament.command.waypoint.originunset",
"Unset the origin of the waypoints. Run /firm waypoints export to save the waypoints with absolute coordinates."))
}
}
thenLiteral("save") {
thenArgument("name", StringArgumentType.string()) { name ->
suggestsList { DataHolder.list().keys }
thenExecute {
val waypoints = Waypoints.useNonEmptyWaypoints()
if (waypoints == null) {
source.sendError(Waypoints.textNothingToExport())
return@thenExecute
}
waypoints.id = get(name)
val exportableWaypoints = createExportableCopy(waypoints)
DataHolder.insert(get(name), exportableWaypoints)
DataHolder.save()
source.sendFeedback(tr("firmament.command.waypoint.saved",
"Saved waypoints locally as ${get(name)}. Use /firm waypoints load to load them again."))
}
}
}
thenLiteral("load") {
thenArgument("name", StringArgumentType.string()) { name ->
suggestsList { DataHolder.list().keys }
thenExecute {
val name = get(name)
val waypoints = DataHolder.list()[name]
if (waypoints == null) {
source.sendError(
tr("firmament.command.waypoint.nosaved",
"No saved waypoint for ${name}. Use tab completion to see available names."))
return@thenExecute
}
loadWaypoints(waypoints, source::sendFeedback)
}
}
}
thenLiteral("export") {
thenExecute {
val waypoints = Waypoints.useNonEmptyWaypoints()
if (waypoints == null) {
source.sendError(Waypoints.textNothingToExport())
return@thenExecute
}
val exportableWaypoints = createExportableCopy(waypoints)
val data = TemplateUtil.encodeTemplate(SHARE_PREFIX, exportableWaypoints)
ClipboardUtils.setTextContent(data)
source.sendFeedback(tr("firmament.command.waypoint.export",
"Copied ${exportableWaypoints.size} waypoints to clipboard in Firmament format."))
}
}
thenLiteral("import") {
thenExecute {
val text = ClipboardUtils.getTextContents()
if (text.startsWith("[")) {
source.sendError(tr("firmament.command.waypoint.import.lookslikecw",
"The waypoints in your clipboard look like they might be ColeWeight waypoints. If so, use /firm waypoints importcw or /firm waypoints importrelativecw."))
return@thenExecute
}
val waypoints = TemplateUtil.maybeDecodeTemplate<FirmWaypoints>(SHARE_PREFIX, text)
if (waypoints == null) {
source.sendError(tr("firmament.command.waypoint.import.error",
"Could not import Firmament waypoints from your clipboard. Make sure they are Firmament compatible waypoints."))
return@thenExecute
}
loadWaypoints(waypoints, source::sendFeedback)
}
}
}
}
}
|