mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-13 08:27:39 +00:00
709ab05713
Only classname and flags are supported right now, and only classname gets set when the entity is added (via the add menu).
252 lines
7.9 KiB
Python
252 lines
7.9 KiB
Python
# vim:ts=4:et
|
|
# ##### 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 #####
|
|
|
|
# copied from io_scene_obj
|
|
|
|
# <pep8 compliant>
|
|
|
|
bl_info = {
|
|
"name": "Quake map format",
|
|
"author": "Bill Currie",
|
|
"blender": (2, 6, 3),
|
|
"api": 35622,
|
|
"location": "File > Import-Export",
|
|
"description": "Import-Export Quake maps",
|
|
"warning": "not even alpha",
|
|
"wiki_url": "",
|
|
"tracker_url": "",
|
|
# "support": 'OFFICIAL',
|
|
"category": "Import-Export"}
|
|
|
|
# To support reload properly, try to access a package var, if it's there,
|
|
# reload everything
|
|
if "bpy" in locals():
|
|
import imp
|
|
if "import_map" in locals():
|
|
imp.reload(import_map)
|
|
if "export_map" in locals():
|
|
imp.reload(export_map)
|
|
|
|
from pprint import pprint
|
|
|
|
import bpy
|
|
from bpy.props import BoolProperty, FloatProperty, StringProperty, EnumProperty
|
|
from bpy.props import FloatVectorProperty, PointerProperty
|
|
from bpy_extras.io_utils import ExportHelper, ImportHelper, path_reference_mode, axis_conversion
|
|
from bpy.app.handlers import persistent
|
|
|
|
from .entityclass import EntityClassDict
|
|
from . import entity
|
|
from . import import_map
|
|
#from . import export_map
|
|
|
|
def ecm_draw(self, context):
|
|
layout = self.layout
|
|
for item in self.menu_items:
|
|
if type(item[1]) is str:
|
|
ec = context.scene.qfmap.entity_classes.entity_classes[item[1]]
|
|
if ec.size:
|
|
icon = 'OBJECT_DATA'
|
|
else:
|
|
icon = 'MESH_DATA'
|
|
op = layout.operator("object.add_entity", text=item[0], icon=icon)
|
|
op.entclass=item[1]
|
|
if ec.comment:
|
|
pass
|
|
else:
|
|
layout.menu(item[1].bl_idname)
|
|
|
|
class EntityClassMenu:
|
|
@classmethod
|
|
def clear(cls):
|
|
while cls.menu_items:
|
|
if type(cls.menu_item[0][1]) is not str:
|
|
bpy.utils.unregister_class(cls.menu_items[0][1])
|
|
cls.menu_items[0][1].clear()
|
|
del cls.menu_items[0]
|
|
@classmethod
|
|
def build(cls, menudict, name="INFO_MT_entity_add", label="entity"):
|
|
items = list(menudict.items())
|
|
items.sort()
|
|
menu_items = []
|
|
for i in items:
|
|
i = list(i)
|
|
if type(i[1]) is dict:
|
|
if i[0]:
|
|
nm = "_".join((name, i[0]))
|
|
else:
|
|
nm = name
|
|
i[1] = cls.build(i[1], nm, i[0])
|
|
menu_items.append(i)
|
|
attrs = {}
|
|
attrs["menu_items"] = menu_items
|
|
attrs["draw"] = ecm_draw
|
|
attrs["bl_idname"] = name
|
|
attrs["bl_label"] = label
|
|
attrs["clear"] = cls.clear
|
|
menu = type(name, (bpy.types.Menu,), attrs)
|
|
bpy.utils.register_class(menu)
|
|
return menu
|
|
|
|
@persistent
|
|
def scene_load_handler(dummy):
|
|
for scene in bpy.data.scenes:
|
|
if hasattr(scene, "qfmap"):
|
|
scene.qfmap.script_update(bpy.context)
|
|
|
|
def ec_dir_update(self, context):
|
|
self.entity_classes.from_source_tree(self.dirpath)
|
|
name = context.scene.name + '-EntityClasses'
|
|
if name in bpy.data.texts:
|
|
txt = bpy.data.texts[name]
|
|
else:
|
|
txt = bpy.data.texts.new(name)
|
|
txt.from_string(self.entity_classes.to_plist())
|
|
self.script = name
|
|
|
|
def ec_script_update(self, context):
|
|
self.script_update(context)
|
|
|
|
class AddEntity(bpy.types.Operator):
|
|
'''Add an entity'''
|
|
bl_idname = "object.add_entity"
|
|
bl_label = "Entity"
|
|
entclass = StringProperty(name = "entclass")
|
|
|
|
def execute(self, context):
|
|
keywords = self.as_keywords()
|
|
return entity.add_entity(self, context, **keywords)
|
|
|
|
class QFEntityClasses(bpy.types.PropertyGroup):
|
|
wadpath = StringProperty(
|
|
name="wadpath",
|
|
description="Path to search for wad files",
|
|
subtype='DIR_PATH')
|
|
dirpath = StringProperty(
|
|
name="dirpath",
|
|
description="Path to qc source tree",
|
|
subtype='DIR_PATH',
|
|
update=ec_dir_update)
|
|
script = StringProperty(
|
|
name="script",
|
|
description="entity class storage",
|
|
update=ec_script_update)
|
|
entity_classes = EntityClassDict()
|
|
ecm = EntityClassMenu.build({})
|
|
|
|
def script_update(self, context):
|
|
if self.script in bpy.data.texts:
|
|
script = bpy.data.texts[self.script].as_string()
|
|
self.entity_classes.from_plist(script)
|
|
menudict = {}
|
|
entclasses = self.entity_classes.entity_classes.keys()
|
|
for ec in entclasses:
|
|
ecsub = ec.split("_")
|
|
d = menudict
|
|
for sub in ecsub[:-1]:
|
|
if sub not in d:
|
|
d[sub] = {}
|
|
elif type(d[sub]) is str:
|
|
d[sub] = {"":d[sub]}
|
|
d = d[sub]
|
|
sub = ecsub[-1]
|
|
if sub in d:
|
|
d[sub][""] = ec
|
|
else:
|
|
d[sub] = ec
|
|
self.__class__.ecm = EntityClassMenu.build(menudict)
|
|
|
|
class QFECPanel(bpy.types.Panel):
|
|
bl_space_type = 'PROPERTIES'
|
|
bl_region_type = 'WINDOW'
|
|
bl_context = 'scene'
|
|
bl_label = 'QF Entity Classes'
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return True
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
scene = context.scene
|
|
layout.prop(scene.qfmap, "wadpath")
|
|
layout.prop(scene.qfmap, "dirpath")
|
|
layout.prop(scene.qfmap, "script")
|
|
|
|
class ImportMap(bpy.types.Operator, ImportHelper):
|
|
'''Load a Quake map File'''
|
|
bl_idname = "import_mesh.quake_map"
|
|
bl_label = "Import map"
|
|
|
|
filename_ext = ".map"
|
|
filter_glob = StringProperty(default="*.map", options={'HIDDEN'})
|
|
|
|
def execute(self, context):
|
|
keywords = self.as_keywords (ignore=("filter_glob",))
|
|
return import_map.import_map(self, context, **keywords)
|
|
|
|
class ExportMap(bpy.types.Operator, ExportHelper):
|
|
'''Save a Quake map File'''
|
|
|
|
bl_idname = "export_mesh.quake_map"
|
|
bl_label = "Export map"
|
|
|
|
filename_ext = ".map"
|
|
filter_glob = StringProperty(default="*.map", options={'HIDDEN'})
|
|
|
|
@classmethod
|
|
def poll(cls, context):
|
|
return (context.active_object != None
|
|
and type(context.active_object.data) == bpy.types.Mesh)
|
|
|
|
def execute(self, context):
|
|
keywords = self.as_keywords (ignore=("check_existing", "filter_glob"))
|
|
return export_map.export_map(self, context, **keywords)
|
|
|
|
def menu_func_import(self, context):
|
|
self.layout.operator(ImportMap.bl_idname, text="Quake map (.map)")
|
|
|
|
def menu_func_export(self, context):
|
|
self.layout.operator(ExportMap.bl_idname, text="Quake map (.map)")
|
|
|
|
def menu_func_add(self, context):
|
|
self.layout.menu(context.scene.qfmap.ecm.bl_idname, icon='PLUGIN')
|
|
|
|
def register():
|
|
bpy.utils.register_module(__name__)
|
|
|
|
bpy.types.Scene.qfmap = PointerProperty(type=QFEntityClasses)
|
|
|
|
bpy.types.INFO_MT_file_import.append(menu_func_import)
|
|
bpy.types.INFO_MT_file_export.append(menu_func_export)
|
|
bpy.types.INFO_MT_add.append(menu_func_add)
|
|
|
|
bpy.app.handlers.load_post.append(scene_load_handler)
|
|
entity.register()
|
|
|
|
|
|
def unregister():
|
|
bpy.utils.unregister_module(__name__)
|
|
|
|
bpy.types.INFO_MT_file_import.remove(menu_func_import)
|
|
bpy.types.INFO_MT_file_export.remove(menu_func_export)
|
|
bpy.types.INFO_MT_add.remove(menu_func_add)
|
|
|
|
if __name__ == "__main__":
|
|
register()
|