Skip to content

Commit

Permalink
Drop FormID mismatch checks in CELLs and DIALs
Browse files Browse the repository at this point in the history
CELL and DIAL FormIDs don't need to be compared - we index the Mob*
classes based on those FormIDs, so they're guaranteed to be equal. Those
checks are just wasted performance.

PGRD and LAND are more interesting. The game treats any occurence of
these as a CELL child the same way, whether they are new records or
overrides. So it is legitimate to have conflicting FormIDs here and we
can't check it.

This means that the checks in MobCell and MobDial have to go. The checks
in MobWorld probably do as well, but I can't say that for sure yet, so
leaving them in - let's see if it blows up at some point.

Improve display of ModFidMismatchError

Should show the FormID as hex via strFid.
  • Loading branch information
Infernio committed Jul 23, 2022
1 parent 7aec9d0 commit c9ca046
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 26 deletions.
33 changes: 9 additions & 24 deletions Mopy/bash/brec/record_groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

# Wrye Bash imports
from .mod_io import GrupHeader, ModReader, RecordHeader, TopGrupHeader
from .utils_constants import group_types, fid_key
from .utils_constants import group_types, fid_key, strFid
from ..bolt import pack_int, structs_cache, attrgetter_cache, deprint, \
sig_to_str, dict_sort
from ..exception import AbstractError, ModError, ModFidMismatchError
Expand Down Expand Up @@ -484,10 +484,6 @@ def merge_records(self, block, loadSet, mergeIds, iiSkipMerge, doFilter):
loadSetIsSuperset = loadSet.issuperset
# First, check the main DIAL record
src_dial = block.dial
src_dial_fid = src_dial.fid
if self.dial.fid != src_dial_fid:
raise ModFidMismatchError(self.inName, u'DIAL', self.dial.fid,
src_dial_fid)
if not src_dial.flags1.ignored:
# If we're Filter-tagged, perform merge filtering first
if doFilter:
Expand All @@ -504,7 +500,7 @@ def merge_records(self, block, loadSet, mergeIds, iiSkipMerge, doFilter):
if not iiSkipMerge:
# We're past all hurdles - mark the record as merged, and stick
# a copy into ourselves
mergeIdsAdd(src_dial_fid)
mergeIdsAdd(src_dial.fid)
self.dial = src_dial.getTypeCopy()
# Now we're ready to filter and merge the INFO children
super(MobDial, self).merge_records(block, loadSet, mergeIds,
Expand All @@ -517,16 +513,12 @@ def updateMasters(self, masterset_add):

def updateRecords(self, srcBlock, mergeIds):
src_dial = srcBlock.dial
src_dial_fid = src_dial.fid
if self.dial.fid != src_dial_fid:
raise ModFidMismatchError(self.inName, u'DIAL', self.dial.fid,
src_dial_fid)
# Copy the latest version of the DIAL record over. We can safely mark
# it as not merged because keepRecords above ensures that we never
# discard a DIAL when it still has INFO children
if not src_dial.flags1.ignored:
self.dial = src_dial.getTypeCopy()
mergeIds.discard(src_dial_fid)
mergeIds.discard(src_dial.fid)
super(MobDial, self).updateRecords(srcBlock, mergeIds)

def _sort_group(self):
Expand Down Expand Up @@ -983,14 +975,9 @@ def updateRecords(self, srcBlock, mergeIds, __attrget=attrgetter(
for attr, (myRecord, record) in zip((u'cell', u'pgrd', u'land'),
self_src_attrs):
if myRecord and record:
src_rec_fid = record.fid
if myRecord.fid != src_rec_fid:
raise ModFidMismatchError(self.inName, myRecord.rec_str,
myRecord.fid, src_rec_fid)
if not record.flags1.ignored:
record = record.getTypeCopy()
setattr(self, attr, record)
mergeDiscard(src_rec_fid)
setattr(self, attr, record.getTypeCopy())
mergeDiscard(record.fid)
for attr, (self_rec_list, src_rec_list) in zip(
(u'persistent_refs', u'temp_refs', u'distant_refs'),
self_src_attrs[3:]):
Expand Down Expand Up @@ -1042,10 +1029,6 @@ def merge_records(self, block, loadSet, mergeIds, iiSkipMerge, doFilter):
continue
# In IIM, skip all merging (duh)
if iiSkipMerge: continue
dest_rec = getattr(self, single_attr)
if dest_rec and dest_rec.fid != src_rec.fid:
raise ModFidMismatchError(self.inName, dest_rec.rec_str,
dest_rec.fid, src_rec.fid)
# We're past all hurdles - stick a copy of this record into
# ourselves and mark it as merged
mergeIdsAdd(src_rec.fid)
Expand Down Expand Up @@ -1540,9 +1523,10 @@ def updateRecords(self, srcBlock, mergeIds):
record = getattr(srcBlock, attr)
if myRecord and record:
src_rec_fid = record.fid
##: This may be wrong, check if ROAD behaves like PGRD/LAND
if myRecord.fid != src_rec_fid:
raise ModFidMismatchError(self.inName, myRecord.rec_str,
myRecord.fid, src_rec_fid)
strFid(myRecord.fid), strFid(src_rec_fid))
if not record.flags1.ignored:
record = record.getTypeCopy()
setattr(self, attr, record)
Expand Down Expand Up @@ -1589,9 +1573,10 @@ def merge_records(self, block, loadSet, mergeIds, iiSkipMerge, doFilter):
# In IIM, skip all merging (duh)
if iiSkipMerge: continue
dest_rec = getattr(self, single_attr)
##: This may be wrong, check if ROAD behaves like PGRD/LAND
if dest_rec and dest_rec.fid != src_rec.fid:
raise ModFidMismatchError(self.inName, dest_rec.rec_str,
dest_rec.fid, src_rec.fid)
strFid(dest_rec.fid), strFid(src_rec.fid))
# We're past all hurdles - stick a copy of this record into
# ourselves and mark it as merged
mergeIdsAdd(src_rec.fid)
Expand Down
4 changes: 2 additions & 2 deletions Mopy/bash/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ class ModFidMismatchError(ModError):
def __init__(self, in_name, debug_str, fid_expected, fid_actual):
debug_str = _join_sigs(debug_str)
message_form = f'{debug_str}: FormIDs do not match - expected ' \
f'{fid_expected!r} but got {fid_actual!r}'
super(ModFidMismatchError, self).__init__(in_name, message_form)
f'{fid_expected} but got {fid_actual}'
super().__init__(in_name, message_form)

class ModSigMismatchError(ModError):
"""Mod Error: A record is getting overridden by a record with a different
Expand Down

0 comments on commit c9ca046

Please sign in to comment.