feat: add ballance map sector field in scene
- add ballance map sector info in scene to indicate the maximum sector count of this map. - this adding will prevent the bug that the exported ballance map do not have successive sector groups. because original implement will not create sector group if no component in corresponding sector and previous remedy still have bug. and if this happended, ballance will show spaceship in wrong sector. this adding is the final solution of this bug. - exlarge ballance map sector info when user adding component. the enlarged value will be calculated by user input sector. - auto enlarge ballance map sector info when importing. this will give user a fluent experience when modifying existing map. - exporting map will also use ballance map sector info to pre-create successive sector group as term 2 stated. - move sector name extractor from virtools file exporting module to naming convention module.
This commit is contained in:
@ -1,9 +1,9 @@
|
||||
import bpy
|
||||
from bpy_extras.wm_utils.progress_report import ProgressReport
|
||||
import tempfile, os, typing, re
|
||||
import tempfile, os, typing
|
||||
from . import PROP_preferences, UTIL_ioport_shared
|
||||
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_icons_manager
|
||||
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture
|
||||
from . import UTIL_virtools_types, UTIL_functions, UTIL_file_browser, UTIL_blender_mesh, UTIL_ballance_texture, UTIL_icons_manager, UTIL_naming_convension
|
||||
from . import PROP_virtools_group, PROP_virtools_material, PROP_virtools_mesh, PROP_virtools_texture, PROP_ballance_map_info
|
||||
from .PyBMap import bmap_wrapper as bmap
|
||||
|
||||
# define global tex save opt blender enum prop helper
|
||||
@ -84,6 +84,11 @@ class BBP_OT_export_virtools(bpy.types.Operator, UTIL_file_browser.ExportVirtool
|
||||
if self.use_compress:
|
||||
box.prop(self, 'compress_level')
|
||||
|
||||
# show sector info to notice user
|
||||
layout.separator()
|
||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||
layout.label(text = f'Map Sectors: {map_info.mSectorCount}')
|
||||
|
||||
_TObj3dPair = tuple[bpy.types.Object, bmap.BM3dObject]
|
||||
_TMeshPair = tuple[bpy.types.Object, bpy.types.Mesh, bmap.BMMesh]
|
||||
_TMaterialPair = tuple[bpy.types.Material, bmap.BMMaterial]
|
||||
@ -170,8 +175,22 @@ def _export_virtools_groups(
|
||||
# start saving
|
||||
progress.enter_substeps(len(obj3d_crets), "Saving Groups")
|
||||
|
||||
# create group exporting helper
|
||||
group_cret_guard: VirtoolsGroupCreationGuard = VirtoolsGroupCreationGuard(writer)
|
||||
# create sector group first
|
||||
# This step is designed for ensure that the created sector group is successive.
|
||||
#
|
||||
# Due to the design of Ballance, Ballance rely on checking the existance of Sector_XX to get how many sectors this map have.
|
||||
# Thus if there are no component in a sector, it still need to create a empty Sector_XX group, otherwise the game will crash
|
||||
# or be ended at a accident sector.
|
||||
#
|
||||
# So we create all needed sector group in here to make sure exported virtools file can be read by Ballancde correctly.
|
||||
map_info: PROP_ballance_map_info.RawBallanceMapInfo = PROP_ballance_map_info.get_raw_ballance_map_info(bpy.context.scene)
|
||||
for i in range(map_info.mSectorCount):
|
||||
gp_name: str = UTIL_naming_convension.build_name_from_sector_index(i + 1)
|
||||
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
|
||||
if vtgroup is None:
|
||||
vtgroup = writer.create_group()
|
||||
vtgroup.set_name(gp_name)
|
||||
group_cret_map[gp_name] = vtgroup
|
||||
|
||||
for obj3d, vtobj3d in obj3d_crets:
|
||||
# open group visitor
|
||||
@ -180,8 +199,8 @@ def _export_virtools_groups(
|
||||
# get group or create new group from guard
|
||||
vtgroup: bmap.BMGroup | None = group_cret_map.get(gp_name, None)
|
||||
if vtgroup is None:
|
||||
# note: no need to set name, guard has set it.
|
||||
vtgroup = group_cret_guard.create_group(gp_name)
|
||||
vtgroup = writer.create_group()
|
||||
vtgroup.set_name(gp_name)
|
||||
group_cret_map[gp_name] = vtgroup
|
||||
|
||||
# group this object
|
||||
@ -471,73 +490,6 @@ def _save_virtools_document(
|
||||
progress.step()
|
||||
progress.leave_substeps()
|
||||
|
||||
class VirtoolsGroupCreationGuard():
|
||||
"""
|
||||
This class is designed for ensure that the created sector group is successive.
|
||||
|
||||
Due to the design of Ballance, Ballance rely on checking the existance of Sector_XX to get how many sectors this map have.
|
||||
Thus if there are no component in a sector, it still need to create a empty Sector_XX group, otherwise the game will crash
|
||||
or be ended at a accident sector.
|
||||
|
||||
This class hook the operation of Virtools group creation and check all Sector group creation.
|
||||
Create essential group to make Sector_XX group successive.
|
||||
Thus all group creation in this module should be passed by this class.
|
||||
"""
|
||||
cRegexGroupSector: typing.ClassVar[re.Pattern] = re.compile('^Sector_(0[1-8]|[1-9][0-9]{1,2}|9)$')
|
||||
|
||||
@staticmethod
|
||||
def __get_group_index(group_name: str) -> int | None:
|
||||
"""
|
||||
Return the sector index of group name if it is. Otherwise None.
|
||||
"""
|
||||
regex_result = VirtoolsGroupCreationGuard.cRegexGroupSector.match(group_name)
|
||||
if regex_result is not None:
|
||||
return int(regex_result.group(1))
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def __get_group_name(group_index: int) -> str:
|
||||
"""
|
||||
Output Sector group name by given sector index
|
||||
"""
|
||||
if group_index == 9:
|
||||
return 'Sector_9'
|
||||
else:
|
||||
return f'Sector_{group_index:0>2d}'
|
||||
|
||||
__mWriter: bmap.BMFileWriter
|
||||
__mSectors: list[bmap.BMGroup]
|
||||
|
||||
def __init__(self, assoc_writer: bmap.BMFileWriter):
|
||||
self.__mWriter = assoc_writer
|
||||
self.__mSectors = []
|
||||
|
||||
def create_group(self, group_name: str) -> bmap.BMGroup:
|
||||
"""
|
||||
The hooked group creation function.
|
||||
|
||||
Please note the passed group name argument is just for name checking.
|
||||
This function will set group name for you, not like BMFileWriter.create_group() operated.
|
||||
"""
|
||||
# check whether it is sector group
|
||||
# note: the return sector index is 1 based, not 0
|
||||
sector_idx: int | None = VirtoolsGroupCreationGuard.__get_group_index(group_name)
|
||||
# if it is regular group, return normal creation
|
||||
if sector_idx is None:
|
||||
gp: bmap.BMGroup = self.__mWriter.create_group()
|
||||
gp.set_name(group_name)
|
||||
return gp
|
||||
|
||||
# get from sector cahce list
|
||||
# enlarge sector cache list if it is not fulfilled given sector index
|
||||
while sector_idx > len(self.__mSectors):
|
||||
gp: bmap.BMGroup = self.__mWriter.create_group()
|
||||
self.__mSectors.append(gp)
|
||||
gp.set_name(self.__get_group_name(len(self.__mSectors)))
|
||||
# return ordered sector from sector caches
|
||||
return self.__mSectors[sector_idx - 1]
|
||||
|
||||
def register() -> None:
|
||||
bpy.utils.register_class(BBP_OT_export_virtools)
|
||||
|
||||
|
Reference in New Issue
Block a user