-
Notifications
You must be signed in to change notification settings - Fork 0
/
mc2mt.py
285 lines (252 loc) · 13.1 KB
/
mc2mt.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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
# io_import_minecraft
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
# bl_info = {
# "name": "Import: Minecraft b1.7+",
# "description": "Importer for viewing Minecraft worlds",
# "author": "Adam Crossan (acro)",
# "version": (1,6,3),
# "blender": (2, 6, 0),
# "api": 41226,
# "location": "File > Import > Minecraft",
# "warning": '', # used for warning icon and text in addons panel
# "wiki_url": "http://randomsamples.info/project/mineblend",
# "category": "Import-Export"}
DEBUG_SCENE=False
# To support reload properly, try to access a package var, if it's there, reload everything
#if "bpy" in locals():
# import imp
# if "mineregion" in locals():
# imp.reload(mineregion)
#import bpy
#from bpy.props import StringProperty, FloatProperty, IntProperty, BoolProperty, EnumProperty
import imp
import mineregion
#def setSceneProps(scn):
# #Set up scene-level properties
# bpy.types.Scene.MCLoadNether = BoolProperty(
# name = "Load Nether",
# description = "Load Nether (if present) instead of Overworld.",
# default = False)
# scn['MCLoadNether'] = False
# return
#setSceneProps(bpy.context.scene)
# def createTestScene():
# bpy.ops.scene.new(type='NEW')
# bpy.context.scene.render.engine = 'CYCLES'
# # plane
# bpy.ops.mesh.primitive_plane_add(radius=1, view_align=True, enter_editmode=False, location=(0,0,0), rotation=(0,0,0), layers = (True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
# bpy.ops.transform.resize(value=(10,10,10), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
# bpy.ops.material.new()
# # cube
# bpy.ops.mesh.primitive_cube_add(radius=1, view_align=True, enter_editmode=False, location=(0,0,0), rotation=(0,0,0), layers = (True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
# # FIXME - error
# #bpy.context.space_data.context='MATERIAL'
# bpy.ops.transform.translate(value=(0.55,0.17,1.14), constraint_axis=(False,False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
# # set material to leaves?
# bpy.ops.object.editmode_toggle()
# bpy.ops.uv.unwrap(method='CONFORMAL', margin=0.001)
# # uv mapping - how do we tell blender?
# #bpy.ops.transform.resize(value=(0.0368432,0.0368432,0.0368432), constraint_axis=(False,False,False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)
# #bpy.ops.transform.translate(value=(-0.202301, 0.07906, 0), constraint_axis=(False,False,False), constraint_orientation='GLOBAL', mirror=False, proportional_falloff='SMOOTH', proportional_size=1)
# bpy.ops.object.editmode_toggle()
# # lights...
# bpy.ops.object.lamp_add(type='SUN', view_align=True, location=(-8.12878,5.39259,9.70453), rotation=(-0.383973,0,0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
# # camera...
# bpy.ops.object.camera_add(view_align=True, enter_editmode=False, location=(-8.12878,-9.13302,7.87796), rotation=(0,0,0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
# #bpy.context.space_data.context='CONSTRAINT'
# bpy.ops.object.constraint_add(type='TRACK_TO')
# bpy.context.object.constraints["Track To"].target = bpy.data.objects["Cube.001"]
# bpy.context.object.constraints["Track To"].track_axis = 'TRACK_NEGATIVE_Z'
# bpy.context.object.constraints["Track To"].up_axis = 'UP_Y'
#Menu 'button' for the import menu (which calls the world selector)...
# class MinecraftWorldSelector(bpy.types.Operator):
#"""An operator defining a dialogue for choosing one on-disk Minecraft world to load.
#This supplants the need to call the file selector, since
"""Minecraft worlds require a preset specific folder structure of multiple files which cannot be selected singly."""
bl_idname = "mcraft.selectworld"
bl_label = "Select Minecraft World"
#bl_space_type = "PROPERTIES"
#Possible placements for these:
bl_region_type = "WINDOW"
#TODO: Make this much more intuitive for the user!
#Would be better if could define min[x,y,z] and max[x,y,z] and load between these point
mcLoadAtCursor = False #Loads as if 3D cursor offset in viewport was the player (load) position.
mcLowLimit = 60 #The lowest depth layer to load. (High=256, Sea=64, Low=0)
mcHighLimit = 128 #The highest layer to load. (High=256, Sea=64, Low=0)
mcLoadRadius = 5 # 'Load Radius - The half-width of the load range around load-pos.
# e.g, 4 will load 9x9 chunks around the load centre
# WARNING! Above 10, this gets slow and eats LOTS of memory!
mcOmitStone = False # When True, do not import common blocks such as stone & dirt blocks (overworld) or netherrack (nether).
mcDimenSelectList = '0' #Which dimension should be loaded? - 0=Overworld; 1=Nether, 2=The End
mcShowSlimeSpawns = False #'Display green markers showing slime-spawn locations
mcUseCyclesMats = False #Blender Setting: Set up default materials for use with Cycles Render Engine instead of Blender Internal
mcFasterViewport = False #Blender Setting: Disable display of common blocks (stone, dirt, etc.) in the viewport for better performance.
mcSurfaceOnly = False #Omit underground blocks. Significantly better viewing and rendering performance.
mcOmitMobs = True # When True, do not load mobs (creepers, skeletons, zombies, etc.) in world
#may need to define loadnether and loadend as operators...?
# omit Dirt toggle option.
# height-limit option (only load down to a specific height) -- could be semi-dynamic and delve deeper when air value for the
# column in question turns out to be lower than the loading threshold anyway.
#surfaceOnly ==> only load surface, discard underground areas. Doesn't count for nether.
# Load Nether is, obviously, only available if selected world has nether)
# Load End. Who has The End?! Not I!
#When specifying a property of type EnumProperty, ensure you call the constructing method correctly.
#Note that items is a set of (identifier, value, description) triples, and default is a string unless you switch on options=ENUM_FLAG in which case make default a set of 1 string.
#Need a better way to handle this variable: (possibly set it as a screen property)
# import mineregion
wlist = mineregion.getWorldSelectList()
if wlist is not None:
revwlist = wlist[::-1]
mcWorldSelectList = 0 #Which Minecraft save should be loaded?
else:
mcWorldSelectList = 0 #Which Minecraft save should be loaded?
#TODO: on select, check presence of DIM-1 etc.
print("List of Worlds: wlist:: ", wlist)
netherWorlds = [w[0] for w in wlist if mineregion.hasNether(w[0])]
print("List of worlds with Nether: ", netherWorlds)
endWorlds = [e[0] for e in wlist if mineregion.hasEnd(e[0])]
print("List of worlds with The End: ", endWorlds)
#my_worldlist = bpy.props.EnumProperty(items=[('0', "A", "The A'th item"), ('1', 'B', "Bth item"), ('2', 'C', "Cth item"), ('3', 'D', "dth item"), ('4', 'E', 'Eth item')][::-1], default='2', name="World", description="Which Minecraft save should be loaded?")
# def execute(self, context):
#self.report({"INFO"}, "Loading world: " + str(self.mcWorldSelectList))
#thread.sleep(30)
#self.report({"WARNING"}, "Foo!")
#from . import mineregion
# scn = context.scene
mcLoadDimenNether = True if mcDimenSelectList=='1' else False
mcLoadDimenEnd = True if mcDimenSelectList=='2' else False
# FIXME - when omitmobs is false, mobs will sometimes still not be imported (related to reload issue?)
opts = {"omitstone": mcOmitStone, "showslimes": mcShowSlimeSpawns, "atcursor": mcLoadAtCursor,
"highlimit": mcHighLimit, "lowlimit": mcLowLimit,
"loadnether": mcLoadDimenNether, "loadend": mcLoadDimenEnd,
"usecycles": mcUseCyclesMats, "omitmobs": mcOmitMobs,
"fasterViewport": mcFasterViewport, "surfaceOnly": mcSurfaceOnly}
#print(str(opts))
#get selected world name instead via bpy.ops.mcraft.worldselected -- the enumeration as a property/operator...?
mineregion.readMinecraftWorld(str(mcWorldSelectList), mcLoadRadius, opts)
# for s in bpy.context.area.spaces: # iterate all space in the active area
# if s.type == "VIEW_3D": # check if space is a 3d-view
# space = s
# space.clip_end = 10000.0
#run minecraftLoadChunks
#if DEBUG_SCENE:
# createTestScene()
# return {'FINISHED'}
# def invoke(self, context, event):
# context.window_manager.invoke_props_dialog(self, width=350,height=250)
# return {'RUNNING_MODAL'}
#
#
# def draw(self, context):
# layout = self.layout
# col = layout.column()
# col.label(text="Choose import options")
#
# row = col.row()
# row.prop(self, "mcLoadAtCursor")
#
# row = col.row()
#
# sub = col.split(percentage=0.5)
# colL = sub.column(align=True)
# colL.prop(self, "mcShowSlimeSpawns")
#
# cycles = None
# if hasattr(bpy.context.scene, 'cycles'):
# cycles = bpy.context.scene.cycles
# row2 = col.row()
# if cycles is not None:
# row2.active = (cycles is not None)
# row2.prop(self, "mcUseCyclesMats")
#
# row3 = col.row()
# row3.prop(self, "mcOmitStone")
# row3.prop(self, "mcOmitMobs")
#
# row = col.row()
# row.prop(self,"mcFasterViewport")
# #row.prop(self,"mcSurfaceOnly")
#
# #if cycles:
# #like this from properties_data_mesh.py:
# ##layout = self.layout
# ##mesh = context.mesh
# ##split = layout.split()
# ##col = split.column()
# ##col.prop(mesh, "use_auto_smooth")
# ##sub = col.column()
# ##sub.active = mesh.use_auto_smooth
# ##sub.prop(mesh, "auto_smooth_angle", text="Angle")
# #row.operator(
# #row.prop(self, "mcLoadEnd") #detect folder first (per world...)
#
# #label: "loading limits"
# row = layout.row()
# row.prop(self, "mcLowLimit")
# row = layout.row()
# row.prop(self, "mcHighLimit")
# row = layout.row()
# row.prop(self, "mcLoadRadius")
#
# row = layout.row()
# row.prop(self, "mcDimenSelectList")
# #col = layout.column()
#
# row = layout.row()
# row.prop(self, "mcWorldSelectList")
# #row.operator("mcraft.worldlist", icon='')
# col = layout.column()
# def worldchange(self, context):
# ##UPDATE (ie read then write back the value of) the property in the panel
# #that needs to be updated. ensure it's in the scene so we can get it...
# #bpy.ops.mcraft.selectworld('INVOKE_DEFAULT')
# #if the new world selected has nether, then update the nether field...
# #in fact, maybe do that even if it doesn't.
# #context.scene['MCLoadNether'] = True
# return {'FINISHED'}
#
# class MineMenuItemOperator(bpy.types.Operator):
# bl_idname = "mcraft.launchselector"
# bl_label = "Needs label but label not used"
#
# def execute(self, context):
# bpy.ops.mcraft.selectworld('INVOKE_DEFAULT')
# return {'FINISHED'}
#
# bpy.utils.register_class(MinecraftWorldSelector)
# bpy.utils.register_class(MineMenuItemOperator)
#bpy.utils.register_class(MCraft_PT_worldlist)
#Forumsearch tip!! FINDME:
#Another way would be to update a property that is displayed in your panel via layout.prop(). AFAIK these are watched and cause a redraw on update.
#
# def mcraft_filemenu_func(self, context):
# self.layout.operator("mcraft.launchselector", text="Minecraft (.region)", icon='MESH_CUBE')
#
#
# def register():
# #bpy.utils.register_module(__name__)
# bpy.types.INFO_MT_file_import.append(mcraft_filemenu_func) # adds the operator action func to the filemenu
#
# def unregister():
# #bpy.utils.unregister_module(__name__)
# bpy.types.INFO_MT_file_import.remove(mcraft_filemenu_func) # removes the operator action func from the filemenu
#
# if __name__ == "__main__":
# register()