-
Notifications
You must be signed in to change notification settings - Fork 109
/
waypoints.py
152 lines (133 loc) · 7.08 KB
/
waypoints.py
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
from pymclevel import nbt
import os
import logging
import shutil
log = logging.getLogger()
class WaypointManager:
'''
Class for handling the API to load and save waypoints
'''
def __init__(self, worldDir=None, editor=None):
self.worldDirectory = worldDir
self.waypoints = {}
self.waypoint_names = set()
self.editor = editor
self.nbt_waypoints = nbt.TAG_Compound()
self.nbt_waypoints["Waypoints"] = nbt.TAG_List()
self.already_saved = False
self.load()
def build(self):
'''
Builds the raw NBT data from the 'mcedit_waypoints.dat' file to a readable dictionary, with the key being '<Name> (<X>,<Y>,<Z>)' and the values being a list of [<X>,<Y>,<Z>,<Yaw>,<Pitch>,<Dimension>]
'''
for point in self.nbt_waypoints["Waypoints"]:
self.waypoint_names.add(point["Name"].value)
self.waypoints["{0} ({1},{2},{3})".format(point["Name"].value, int(point["Coordinates"][0].value), int(point["Coordinates"][1].value), int(point["Coordinates"][2].value))] = [
point["Coordinates"][0].value,
point["Coordinates"][1].value,
point["Coordinates"][2].value,
point["Rotation"][0].value,
point["Rotation"][1].value,
point["Dimension"].value
]
def load(self):
'''
Loads the 'mcedit_waypoints.dat' file from the world directory if it exists. If it doesn't exist, it sets the 'Empty' waypoint
'''
if self.editor.level is None:
return
if not os.path.exists(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat")):
self.build()
else:
try:
self.nbt_waypoints = nbt.load(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"))
except nbt.NBTFormatError as e:
shutil.move(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"), os.path.join(self.worldDirectory, u"mcedit_waypoints_backup.dat"))
log.error(e)
log.warning("Waypoint data file corrupted, ignoring...")
finally:
self.build()
if not (len(self.waypoints) > 0):
self.waypoints["Empty"] = [0,0,0,0,0,0]
if "LastPosition" in self.nbt_waypoints:
self.editor.gotoLastWaypoint(self.nbt_waypoints["LastPosition"])
del self.nbt_waypoints["LastPosition"]
def save(self):
'''
Saves all waypoint information to the 'mcedit_waypoints.dat' file in the world directory
'''
del self.nbt_waypoints["Waypoints"]
self.nbt_waypoints["Waypoints"] = nbt.TAG_List()
for waypoint in self.waypoints.keys():
if waypoint.split()[0] == "Empty":
continue
way = nbt.TAG_Compound()
way["Name"] = nbt.TAG_String(waypoint.split()[0])
way["Dimension"] = nbt.TAG_Int(self.waypoints[waypoint][5])
coords = nbt.TAG_List()
coords.append(nbt.TAG_Float(self.waypoints[waypoint][0]))
coords.append(nbt.TAG_Float(self.waypoints[waypoint][1]))
coords.append(nbt.TAG_Float(self.waypoints[waypoint][2]))
rot = nbt.TAG_List()
rot.append(nbt.TAG_Float(self.waypoints[waypoint][3]))
rot.append(nbt.TAG_Float(self.waypoints[waypoint][4]))
way["Coordinates"] = coords
way["Rotation"] = rot
self.nbt_waypoints["Waypoints"].append(way)
self.nbt_waypoints.save(os.path.join(self.worldDirectory, u"mcedit_waypoints.dat"))
def add_waypoint(self, name, coordinates, rotation, dimension):
'''
Adds a waypoint to the current dictionary of waypoints
:param name: Name of the Waypoint
:type name: str
:param coordinates: The coordinates of the Waypoint (in X,Y,Z order)
:type coordinates: tuple
:param rotation: The rotation of the current camera viewport (in Yaw,Pitch order)
:type rotation: tuple
:param dimension: The current dimenstion the camera viewport is in
:type dimension: int
'''
formatted_name = "{0} ({1},{2},{3})".format(name, coordinates[0], coordinates[1], coordinates[2])
data = coordinates + rotation + (dimension,)
self.waypoint_names.add(name)
self.waypoints[formatted_name] = data
def delete(self, choice):
'''
Deletes the specified waypoint name from the dictionary of waypoints
:param choice: Name of the waypoint to delete
:type choice: str
'''
waypt = None
for waypoint in self.waypoint_names:
if choice.startswith(waypoint):
waypt = waypoint
if waypt:
self.waypoint_names.remove(waypt)
del self.waypoints[choice]
self.save()
if not (len(self.waypoints) > 0):
self.waypoints["Empty"] = [0,0,0,0,0,0]
def saveLastPosition(self, mainViewport, dimension):
'''
Saves the final position of the camera viewport when the world is closed or MCEdit is exited
:param mainViewport: The reference to viewport object
:param dimension: The dimension the camera viewport is currently in
:type dimension: int
'''
log.info('Saving last position.')
if "LastPosition" in self.nbt_waypoints:
del self.nbt_waypoints["LastPosition"]
topTag = nbt.TAG_Compound()
topTag["Dimension"] = nbt.TAG_Int(dimension)
pos = nbt.TAG_List()
pos.append(nbt.TAG_Float(mainViewport.cameraPosition[0]))
pos.append(nbt.TAG_Float(mainViewport.cameraPosition[1]))
pos.append(nbt.TAG_Float(mainViewport.cameraPosition[2]))
topTag["Coordinates"] = pos
rot = nbt.TAG_List()
rot.append(nbt.TAG_Float(mainViewport.yaw))
rot.append(nbt.TAG_Float(mainViewport.pitch))
topTag["Rotation"] = rot
self.nbt_waypoints["LastPosition"] = topTag
self.save()
self.already_saved = True