Copy disabled (too large)
Download .txt
Showing preview only (17,908K chars total). Download the full file to get everything.
Repository: matortheeternal/smash
Branch: master
Commit: 60c8b34bced6
Files: 708
Total size: 17.0 MB
Directory structure:
gitextract_wihtrx14/
├── .gitignore
├── ESPs/
│ ├── SmashTestPlugin01.esp
│ ├── SmashTestPlugin02.esp
│ └── SmashTestPlugin03.esp
├── LICENSE.txt
├── README.md
├── design/
│ ├── code snippets/
│ │ ├── GetMasterElement.pas
│ │ ├── Mator Smash v0.9.pas
│ │ └── better build algorithm.pas
│ ├── diagrams/
│ │ └── Mator Smash.vpp
│ └── notes/
│ ├── algorithm problems.txt
│ ├── handling.txt
│ ├── high level design.txt
│ ├── linking explanation.txt
│ └── todos 1024.txt
├── frontend/
│ ├── MatorSmash.dpr
│ ├── MatorSmash.dproj
│ ├── MatorSmash.mes
│ ├── MatorSmash.res
│ ├── ModelSupport_MatorSmash/
│ │ ├── MatorSmash/
│ │ │ └── default.txvpck
│ │ ├── default.txvpck
│ │ ├── msEditForm/
│ │ │ └── default.txvpck
│ │ ├── msFrontend/
│ │ │ └── default.txvpck
│ │ ├── msOptionsForm/
│ │ │ └── default.txvpck
│ │ ├── msProfileForm/
│ │ │ └── default.txvpck
│ │ ├── msProfilePanel/
│ │ │ └── default.txvpck
│ │ ├── msSmashForm/
│ │ │ └── default.txvpck
│ │ ├── msSplashForm/
│ │ │ └── default.txvpck
│ │ └── msThreads/
│ │ └── default.txvpck
│ ├── lang/
│ │ └── english.lang
│ ├── msAlgorithm.pas
│ ├── msChoicePanel.pas
│ ├── msConfiguration.pas
│ ├── msConflict.pas
│ ├── msConflictForm.dfm
│ ├── msConflictForm.pas
│ ├── msCore.pas
│ ├── msEditForm.dfm
│ ├── msEditForm.pas
│ ├── msLoader.pas
│ ├── msOptionsForm.dfm
│ ├── msOptionsForm.pas
│ ├── msPluginSelectionForm.dfm
│ ├── msPluginSelectionForm.pas
│ ├── msPriorityForm.dfm
│ ├── msPriorityForm.pas
│ ├── msProfileForm.dfm
│ ├── msProfileForm.pas
│ ├── msProfilePanel.pas
│ ├── msSettingsManager.dfm
│ ├── msSettingsManager.pas
│ ├── msSmash.pas
│ ├── msSmashForm.dfm
│ ├── msSmashForm.pas
│ ├── msSplashForm.dfm
│ ├── msSplashForm.pas
│ ├── msTagHelper.dfm
│ ├── msTagHelper.pas
│ ├── msTagManager.dfm
│ ├── msTagManager.pas
│ ├── msThreads.pas
│ ├── settings/
│ │ ├── Fallout3/
│ │ │ └── Smash.All.json
│ │ ├── Fallout4/
│ │ │ └── Smash.All.json
│ │ ├── FalloutNV/
│ │ │ └── Smash.All.json
│ │ ├── Oblivion/
│ │ │ ├── Bash.Actors.ACBS.json
│ │ │ ├── Bash.Actors.AIData.json
│ │ │ ├── Bash.Actors.AIPackages.json
│ │ │ ├── Bash.Actors.Animations.json
│ │ │ ├── Bash.Actors.CombatStyle.json
│ │ │ ├── Bash.Actors.DeathItem.json
│ │ │ ├── Bash.Actors.Skeleton.json
│ │ │ ├── Bash.Actors.Spells.json
│ │ │ ├── Bash.Actors.Stats.json
│ │ │ ├── Bash.Body-F.json
│ │ │ ├── Bash.Body-M.json
│ │ │ ├── Bash.Body-Size-F.json
│ │ │ ├── Bash.Body-Size-M.json
│ │ │ ├── Bash.C.Climate.json
│ │ │ ├── Bash.C.Light.json
│ │ │ ├── Bash.C.Music.json
│ │ │ ├── Bash.C.Name.json
│ │ │ ├── Bash.C.Owner.json
│ │ │ ├── Bash.C.RecordFlags.json
│ │ │ ├── Bash.C.Water.json
│ │ │ ├── Bash.Creatures.Blood.json
│ │ │ ├── Bash.Eyes.json
│ │ │ ├── Bash.Factions.json
│ │ │ ├── Bash.Graphics.json
│ │ │ ├── Bash.Hair.json
│ │ │ ├── Bash.Invent.json
│ │ │ ├── Bash.Lev.json
│ │ │ ├── Bash.NPC.Class.json
│ │ │ ├── Bash.NPC.Race.json
│ │ │ ├── Bash.Names.json
│ │ │ ├── Bash.Npc.EyesOnly.json
│ │ │ ├── Bash.Npc.HairOnly.json
│ │ │ ├── Bash.NpcFaces.json
│ │ │ ├── Bash.NpcFacesForceFullImport.json
│ │ │ ├── Bash.R.AddSpells.json
│ │ │ ├── Bash.R.Attributes-F.json
│ │ │ ├── Bash.R.Attributes-M.json
│ │ │ ├── Bash.R.ChangeSpells.json
│ │ │ ├── Bash.R.Description.json
│ │ │ ├── Bash.Relations.json
│ │ │ ├── Bash.Scripts.json
│ │ │ ├── Bash.Sound.json
│ │ │ ├── Bash.SpellStats.json
│ │ │ ├── Bash.Stats.json
│ │ │ ├── Bash.Voice-F.json
│ │ │ ├── Bash.Voice-M.json
│ │ │ └── Smash.All.json
│ │ └── Skyrim/
│ │ ├── Bash.Actors.ACBS.json
│ │ ├── Bash.Actors.AIData.json
│ │ ├── Bash.Actors.AIPackages.json
│ │ ├── Bash.Actors.AIPackagesMerge.json
│ │ ├── Bash.Actors.CombatStyle.json
│ │ ├── Bash.Actors.DeathItem.json
│ │ ├── Bash.Actors.Spells.json
│ │ ├── Bash.Actors.SpellsMerge.json
│ │ ├── Bash.Actors.Stats.json
│ │ ├── Bash.All.json
│ │ ├── Bash.Body-F.json
│ │ ├── Bash.Body-M.json
│ │ ├── Bash.Body-Size-F.json
│ │ ├── Bash.Body-Size-M.json
│ │ ├── Bash.C.Acoustic.json
│ │ ├── Bash.C.Climate.json
│ │ ├── Bash.C.Encounter.json
│ │ ├── Bash.C.ImageSpace.json
│ │ ├── Bash.C.Light.json
│ │ ├── Bash.C.Location.json
│ │ ├── Bash.C.Music.json
│ │ ├── Bash.C.Name.json
│ │ ├── Bash.C.Owner.json
│ │ ├── Bash.C.RecordFlags.json
│ │ ├── Bash.C.Regions.json
│ │ ├── Bash.C.Water.json
│ │ ├── Bash.Delev.json
│ │ ├── Bash.Eyes.json
│ │ ├── Bash.Factions.json
│ │ ├── Bash.Graphics.json
│ │ ├── Bash.Hairs.json
│ │ ├── Bash.Invent.json
│ │ ├── Bash.Lev.json
│ │ ├── Bash.NPC.Class.json
│ │ ├── Bash.NPC.Race.json
│ │ ├── Bash.Names.json
│ │ ├── Bash.NpcFaces.json
│ │ ├── Bash.NpcFacesForceFullImport.json
│ │ ├── Bash.R.AddSpells.json
│ │ ├── Bash.R.ChangeSpells.json
│ │ ├── Bash.R.Description.json
│ │ ├── Bash.R.Head.json
│ │ ├── Bash.R.Skills.json
│ │ ├── Bash.Relations.json
│ │ ├── Bash.Relev.json
│ │ ├── Bash.Scripts.json
│ │ ├── Bash.Sound.json
│ │ ├── Bash.SpellStats.json
│ │ ├── Bash.Stats.json
│ │ ├── Bash.Voice-F.json
│ │ ├── Bash.Voice-M.json
│ │ ├── Skip.json
│ │ ├── Smash.All.json
│ │ ├── Smash.ForceAll.json
│ │ └── Smash.OverrideAll.json
│ ├── smash.rc
│ └── smash.res
└── lib/
├── Imaging/
│ ├── Imaging.pas
│ ├── ImagingBitmap.pas
│ ├── ImagingCanvases.pas
│ ├── ImagingClasses.pas
│ ├── ImagingColors.pas
│ ├── ImagingComponents.pas
│ ├── ImagingDds.pas
│ ├── ImagingFormats.pas
│ ├── ImagingIO.pas
│ ├── ImagingNetworkGraphics.pas
│ ├── ImagingOptions.inc
│ ├── ImagingTarga.pas
│ ├── ImagingTypes.pas
│ ├── ImagingUtility.pas
│ └── ZLib/
│ ├── dzlib.pas
│ ├── imadler.pas
│ ├── iminfblock.pas
│ ├── iminfcodes.pas
│ ├── iminffast.pas
│ ├── iminftrees.pas
│ ├── iminfutil.pas
│ ├── impaszlib.pas
│ ├── imtrees.pas
│ ├── imzconf.inc
│ ├── imzdeflate.pas
│ ├── imzinflate.pas
│ ├── imzutil.pas
│ └── readme.txt
├── abbrevia/
│ ├── MPL-1_1.txt
│ ├── Readme.html
│ ├── WavPack License.txt
│ ├── examples/
│ │ └── Delphi/
│ │ ├── Abbrexam.dpr
│ │ ├── BaseDlgu.pas
│ │ ├── Basedlgu.dfm
│ │ ├── CabExt.dpr
│ │ ├── CabExt1.dfm
│ │ ├── CabExt1.pas
│ │ ├── CabFind.dpr
│ │ ├── CabFind1.dfm
│ │ ├── CabFind1.pas
│ │ ├── CabView.dpr
│ │ ├── CabView1.dfm
│ │ ├── CabView1.pas
│ │ ├── ComCtrlsDemo.dpr
│ │ ├── ComCtrlsMain.dfm
│ │ ├── ComCtrlsMain.pas
│ │ ├── CompPad.dpr
│ │ ├── Contents.dpr
│ │ ├── Demo.cab
│ │ ├── ExCBrows.dpr
│ │ ├── ExCBrowu.dfm
│ │ ├── ExCBrowu.pas
│ │ ├── ExCf.dpr
│ │ ├── ExCf.res
│ │ ├── ExFilter.dpr
│ │ ├── ExFiltru.dfm
│ │ ├── ExFiltru.pas
│ │ ├── ExZipper.dpr
│ │ ├── ExZippru.dfm
│ │ ├── ExZippru.pas
│ │ ├── FCITest1.dfm
│ │ ├── FCITest1.pas
│ │ ├── Finder.dpr
│ │ ├── MakeCab.dpr
│ │ ├── MakeCab1.dfm
│ │ ├── MakeCab1.pas
│ │ ├── SelfStbv.dpr
│ │ ├── SelfStub.dpr
│ │ ├── SlfStbv1.dfm
│ │ ├── SlfStbv1.pas
│ │ ├── Streams.dpr
│ │ ├── Streams1.dfm
│ │ ├── Streams1.pas
│ │ ├── StrmBmp.dpr
│ │ ├── StrmBmpU.dfm
│ │ ├── StrmBmpU.pas
│ │ ├── StrmPad.dpr
│ │ ├── TpZip.RC
│ │ ├── TpZip.dpr
│ │ ├── TpZip.r32
│ │ ├── TpZip31.HLP
│ │ ├── UContent.dfm
│ │ ├── UContent.pas
│ │ ├── UMain.dfm
│ │ ├── UMain.pas
│ │ ├── Uexample.dfm
│ │ ├── Uexample.pas
│ │ ├── Unzip.dpr
│ │ ├── Unzip.dproj
│ │ ├── Unzip.dproj.2007
│ │ ├── UsingApi.dpr
│ │ ├── Ustrpad.dfm
│ │ ├── Ustrpad.pas
│ │ ├── Uunzip.dfm
│ │ ├── Uunzip.pas
│ │ ├── Uzip.dfm
│ │ ├── Uzip.pas
│ │ ├── ZipReg.dpr
│ │ ├── ZipReg.dproj
│ │ ├── ZipReg.dproj.2007
│ │ ├── ZipReg1.dfm
│ │ ├── ZipReg1.pas
│ │ ├── ZipView.dpr
│ │ ├── ZipView1.dfm
│ │ ├── ZipView1.pas
│ │ ├── Zipper.dpr
│ │ ├── Zipper.dproj
│ │ ├── Zipper.dproj.2007
│ │ ├── dgAbout.dfm
│ │ ├── dgAbout.pas
│ │ ├── makesfx.dpr
│ │ ├── spntst0.dfm
│ │ ├── spntst0.pas
│ │ ├── uCfGenDg.dfm
│ │ ├── uCfGenDg.pas
│ │ ├── uCfMain.dfm
│ │ ├── uCfMain.pas
│ │ ├── uCfNewDg.dfm
│ │ ├── uCfNewDg.pas
│ │ ├── ubasedlg.dfm
│ │ ├── ubasedlg.pas
│ │ ├── ucomppad.dfm
│ │ ├── ucomppad.pas
│ │ ├── udemodlg.dfm
│ │ ├── udemodlg.pas
│ │ ├── ufinder.dfm
│ │ ├── ufinder.pas
│ │ ├── umakesfx.dfm
│ │ ├── umakesfx.pas
│ │ ├── usplash.dfm
│ │ └── usplash.pas
│ ├── localization/
│ │ ├── AbResString.pas.afr
│ │ ├── AbResString.pas.de
│ │ ├── AbResString.pas.fr
│ │ ├── AbResString.pas.nl
│ │ ├── AbResString.pas.ru
│ │ └── AbResString.pas.tr
│ ├── packages/
│ │ ├── Delphi XE/
│ │ │ ├── Abbrevia.dpk
│ │ │ ├── Abbrevia.dproj
│ │ │ ├── Abbrevia.res
│ │ │ ├── AbbreviaVCL.dpk
│ │ │ ├── AbbreviaVCL.dproj
│ │ │ ├── AbbreviaVCL.res
│ │ │ ├── AbbreviaVCLDesign.dpk
│ │ │ ├── AbbreviaVCLDesign.dproj
│ │ │ └── AbbreviaVCLDesign.res
│ │ └── Delphi XE.groupproj
│ └── source/
│ ├── AbArcTyp.pas
│ ├── AbBase.pas
│ ├── AbBitBkt.pas
│ ├── AbBrowse.pas
│ ├── AbBseCLX.pas
│ ├── AbBseVCL.pas
│ ├── AbBzip2.pas
│ ├── AbBzip2Typ.pas
│ ├── AbCBrows.pas
│ ├── AbCView.pas
│ ├── AbCabExt.pas
│ ├── AbCabKit.pas
│ ├── AbCabMak.pas
│ ├── AbCabTyp.pas
│ ├── AbCharset.pas
│ ├── AbComCtrls.pas
│ ├── AbComCtrls.res
│ ├── AbCompnd.pas
│ ├── AbConst.pas
│ ├── AbCrtl.pas
│ ├── AbDefine.inc
│ ├── AbDfBase.pas
│ ├── AbDfCryS.pas
│ ├── AbDfDec.pas
│ ├── AbDfEnc.pas
│ ├── AbDfHufD.pas
│ ├── AbDfInW.pas
│ ├── AbDfOutW.pas
│ ├── AbDfPkMg.pas
│ ├── AbDfStrm.pas
│ ├── AbDfXlat.pas
│ ├── AbDlgDir.dfm
│ ├── AbDlgDir.pas
│ ├── AbDlgPwd.dfm
│ ├── AbDlgPwd.pas
│ ├── AbExcept.pas
│ ├── AbFciFdi.pas
│ ├── AbGzTyp.pas
│ ├── AbHexVw.pas
│ ├── AbLZMA.pas
│ ├── AbLZMAStream.pas
│ ├── AbMeter.pas
│ ├── AbPPMd.pas
│ ├── AbPeCol.dfm
│ ├── AbPeCol.pas
│ ├── AbPeDir.pas
│ ├── AbPeFn.pas
│ ├── AbPePass.pas
│ ├── AbPeVer.dfm
│ ├── AbPeVer.pas
│ ├── AbQCView.pas
│ ├── AbQCmpnd.pas
│ ├── AbQDgDir.pas
│ ├── AbQDgDir.xfm
│ ├── AbQDgPwd.pas
│ ├── AbQDgPwd.xfm
│ ├── AbQHexVw.pas
│ ├── AbQMeter.pas
│ ├── AbQPeCol.pas
│ ├── AbQPeCol.xfm
│ ├── AbQPeDir.pas
│ ├── AbQPeFn.pas
│ ├── AbQPePas.pas
│ ├── AbQPeVer.pas
│ ├── AbQPeVer.xfm
│ ├── AbQView.pas
│ ├── AbQZView.pas
│ ├── AbQZpOut.pas
│ ├── AbReg.pas
│ ├── AbReg.res
│ ├── AbRegClx.pas
│ ├── AbRegLinux.pas
│ ├── AbRegVcl.pas
│ ├── AbResString.pas
│ ├── AbSWStm.pas
│ ├── AbSelfEx.pas
│ ├── AbSpanSt.pas
│ ├── AbTarTyp.pas
│ ├── AbUnzOutStm.pas
│ ├── AbUnzPrc.pas
│ ├── AbUnzper.pas
│ ├── AbUtils.pas
│ ├── AbVMStrm.pas
│ ├── AbView.pas
│ ├── AbWavPack.pas
│ ├── AbZBrows.pas
│ ├── AbZLTyp.pas
│ ├── AbZView.pas
│ ├── AbZipExt.pas
│ ├── AbZipKit.pas
│ ├── AbZipOut.pas
│ ├── AbZipOut.res
│ ├── AbZipPrc.pas
│ ├── AbZipTyp.pas
│ ├── AbZipper.pas
│ ├── COM/
│ │ ├── Abbrevia.dpr
│ │ ├── Abbrevia.dproj
│ │ ├── Abbrevia.res
│ │ ├── Abbrevia.ridl
│ │ ├── Abbrevia.tlb
│ │ ├── Abbrevia_TLB.pas
│ │ ├── Readme.txt
│ │ ├── _GZipItem.pas
│ │ ├── _TarItem.pas
│ │ ├── _ZipItem.pas
│ │ └── _ZipKit.pas
│ ├── Win32/
│ │ ├── CarrylessRangeCoder.obj
│ │ ├── LzFind.obj
│ │ ├── LzFindMt.obj
│ │ ├── LzmaDec.obj
│ │ ├── LzmaEnc.obj
│ │ ├── PPMdContext.obj
│ │ ├── PPMdSubAllocatorVariantI.obj
│ │ ├── PPMdVariantI.obj
│ │ ├── Threads.obj
│ │ ├── blocksort.obj
│ │ ├── bzlib.obj
│ │ ├── compress.obj
│ │ ├── decompress.obj
│ │ ├── huffman.obj
│ │ ├── wv_bits.obj
│ │ ├── wv_extra1.obj
│ │ ├── wv_extra2.obj
│ │ ├── wv_float.obj
│ │ ├── wv_metadata.obj
│ │ ├── wv_pack.obj
│ │ ├── wv_tags.obj
│ │ ├── wv_unpack.obj
│ │ ├── wv_unpack3.obj
│ │ ├── wv_words.obj
│ │ └── wv_wputils.obj
│ └── Win64/
│ ├── CarrylessRangeCoder.obj
│ ├── LzFind.obj
│ ├── LzFindMt.obj
│ ├── LzmaDec.obj
│ ├── LzmaEnc.obj
│ ├── PPMdContext.obj
│ ├── PPMdSubAllocatorVariantI.obj
│ ├── PPMdVariantI.obj
│ ├── Threads.obj
│ ├── blocksort.obj
│ ├── bzlib.obj
│ ├── compress.obj
│ ├── decompress.obj
│ ├── huffman.obj
│ ├── wv_bits.obj
│ ├── wv_extra1.obj
│ ├── wv_extra2.obj
│ ├── wv_float.obj
│ ├── wv_metadata.obj
│ ├── wv_pack.obj
│ ├── wv_tags.obj
│ ├── wv_unpack.obj
│ ├── wv_unpack3.obj
│ ├── wv_words.obj
│ └── wv_wputils.obj
├── mte/
│ ├── CRC32.pas
│ ├── RttiIni.pas
│ ├── RttiJson.pas
│ ├── RttiTranslation.pas
│ ├── W7Taskbar.pas
│ ├── mteBase.pas
│ ├── mteChangeLogForm.dfm
│ ├── mteChangeLogForm.pas
│ ├── mteHelpers.pas
│ ├── mteLogger.pas
│ ├── mteLogging.pas
│ ├── mtePluginSelectionForm.dfm
│ ├── mtePluginSelectionForm.pas
│ ├── mteProgressForm.dfm
│ ├── mteProgressForm.pas
│ ├── mteTaskHandler.pas
│ └── mteTracker.pas
├── superobject/
│ └── superobject.pas
├── xedit/
│ ├── lz4/
│ │ ├── lz4.pas
│ │ ├── lz4Common.pas
│ │ ├── lz4HC.pas
│ │ ├── lz4frame.pas
│ │ ├── lz4frame_static.pas
│ │ ├── lz4io.pas
│ │ └── xxHash.pas
│ ├── wbBSA.pas
│ ├── wbDefines.inc
│ ├── wbDefinitionsFNV.pas
│ ├── wbDefinitionsFO3.pas
│ ├── wbDefinitionsFO4.pas
│ ├── wbDefinitionsTES3.pas
│ ├── wbDefinitionsTES4.pas
│ ├── wbDefinitionsTES5.pas
│ ├── wbHelpers.pas
│ ├── wbImplementation.pas
│ ├── wbInit.pas
│ ├── wbInterface.pas
│ ├── wbLocalization.pas
│ ├── wbSort.pas
│ ├── wbStreams.pas
│ └── zlib/
│ ├── ZLibEx.inc
│ ├── ZLibExApi.pas
│ ├── win32/
│ │ ├── adler32.obj
│ │ ├── compress.obj
│ │ ├── crc32.obj
│ │ ├── deflate.obj
│ │ ├── infback.obj
│ │ ├── inffast.obj
│ │ ├── inflate.obj
│ │ ├── inftrees.obj
│ │ └── trees.obj
│ ├── win64/
│ │ ├── adler32.obj
│ │ ├── compress.obj
│ │ ├── crc32.obj
│ │ ├── deflate.obj
│ │ ├── infback.obj
│ │ ├── inffast.obj
│ │ ├── inflate.obj
│ │ ├── inftrees.obj
│ │ └── trees.obj
│ └── zlibex.pas
└── zeosdbo/
├── doc/
│ └── html/
│ ├── bugreporting.html
│ ├── buildingtests.html
│ ├── changes.html
│ ├── ede.css
│ ├── installation.html
│ ├── knownbugs.html
│ ├── license.html
│ ├── overview.html
│ ├── parameters.html
│ └── readme.html
├── packages/
│ └── DelphiXE/
│ ├── ZComponent.dpk
│ ├── ZComponent.dproj
│ ├── ZComponent.res
│ ├── ZComponentDesign.dpk
│ ├── ZComponentDesign.dproj
│ ├── ZComponentDesign.res
│ ├── ZCore.dpk
│ ├── ZCore.dproj
│ ├── ZCore.res
│ ├── ZDbc.dpk
│ ├── ZDbc.dproj
│ ├── ZDbc.res
│ ├── ZPackages.inc
│ ├── ZParseSql.dpk
│ ├── ZParseSql.dproj
│ ├── ZParseSql.res
│ ├── ZPlain.dpk
│ ├── ZPlain.dproj
│ ├── ZPlain.res
│ ├── ZeosDbo.groupproj
│ └── events good.txt
└── src/
├── Zeos.inc
├── ZeosLazarus.inc
├── component/
│ ├── ZAbstractConnection.pas
│ ├── ZAbstractDataset.pas
│ ├── ZAbstractRODataset.pas
│ ├── ZAbstractTable.pas
│ ├── ZComponent.dcr
│ ├── ZComponent.inc
│ ├── ZComponentReg.lrs
│ ├── ZComponentReg.pas
│ ├── ZConnection.pas
│ ├── ZConnectionGroup.pas
│ ├── ZDataset.pas
│ ├── ZDatasetUtils.pas
│ ├── ZGroupedConnection.pas
│ ├── ZIBEventAlerter.pas
│ ├── ZPgEventAlerter.pas
│ ├── ZPropertyEditor.pas
│ ├── ZQuerySQLEditor.pas
│ ├── ZROSqlEditor.pas
│ ├── ZSequence.pas
│ ├── ZSqlMetadata.pas
│ ├── ZSqlMonitor.pas
│ ├── ZSqlProcessor.pas
│ ├── ZSqlStrings.pas
│ ├── ZSqlTestForm.pas
│ ├── ZSqlUpdate.pas
│ ├── ZStoredProcedure.pas
│ ├── ZStreamBlob.pas
│ ├── ZUpdateSqlEditor.dfm
│ ├── ZUpdateSqlEditor.lfm
│ ├── ZUpdateSqlEditor.lrs
│ └── ZUpdateSqlEditor.pas
├── core/
│ ├── ZClasses.pas
│ ├── ZCollections.pas
│ ├── ZCompatibility.pas
│ ├── ZCore.inc
│ ├── ZEncoding.pas
│ ├── ZExprParser.pas
│ ├── ZExprToken.pas
│ ├── ZExpression.pas
│ ├── ZFunctions.pas
│ ├── ZFunctionsConvert.pas
│ ├── ZFunctionsDateTime.pas
│ ├── ZFunctionsMath.pas
│ ├── ZFunctionsOther.pas
│ ├── ZFunctionsStrings.pas
│ ├── ZMatchPattern.pas
│ ├── ZMessages.pas
│ ├── ZSysUtils.pas
│ ├── ZTokenizer.pas
│ ├── ZURL.pas
│ ├── ZVariables.pas
│ └── ZVariant.pas
├── dbc/
│ ├── ZDbc.inc
│ ├── ZDbcASA.pas
│ ├── ZDbcASAMetadata.pas
│ ├── ZDbcASAResultSet.pas
│ ├── ZDbcASAStatement.pas
│ ├── ZDbcASAUtils.pas
│ ├── ZDbcAdo.pas
│ ├── ZDbcAdoMetadata.pas
│ ├── ZDbcAdoResultSet.pas
│ ├── ZDbcAdoStatement.pas
│ ├── ZDbcAdoUtils.pas
│ ├── ZDbcCache.pas
│ ├── ZDbcCachedResultSet.pas
│ ├── ZDbcConnection.pas
│ ├── ZDbcDbLib.pas
│ ├── ZDbcDbLibMetadata.pas
│ ├── ZDbcDbLibResultSet.pas
│ ├── ZDbcDbLibStatement.pas
│ ├── ZDbcDbLibUtils.pas
│ ├── ZDbcGenericResolver.pas
│ ├── ZDbcInterbase6.pas
│ ├── ZDbcInterbase6Metadata.pas
│ ├── ZDbcInterbase6ResultSet.pas
│ ├── ZDbcInterbase6Statement.pas
│ ├── ZDbcInterbase6Utils.pas
│ ├── ZDbcIntfs.pas
│ ├── ZDbcLogging.pas
│ ├── ZDbcMetadata.pas
│ ├── ZDbcMySql.pas
│ ├── ZDbcMySqlMetadata.pas
│ ├── ZDbcMySqlResultSet.pas
│ ├── ZDbcMySqlStatement.pas
│ ├── ZDbcMySqlUtils.pas
│ ├── ZDbcOracle.pas
│ ├── ZDbcOracleMetadata.pas
│ ├── ZDbcOracleResultSet.pas
│ ├── ZDbcOracleStatement.pas
│ ├── ZDbcOracleUtils.pas
│ ├── ZDbcPooled.pas
│ ├── ZDbcPostgreSql.pas
│ ├── ZDbcPostgreSqlMetadata.pas
│ ├── ZDbcPostgreSqlResultSet.pas
│ ├── ZDbcPostgreSqlStatement.pas
│ ├── ZDbcPostgreSqlUtils.pas
│ ├── ZDbcResultSet.pas
│ ├── ZDbcResultSetMetadata.pas
│ ├── ZDbcSqLite.pas
│ ├── ZDbcSqLiteMetadata.pas
│ ├── ZDbcSqLiteResultSet.pas
│ ├── ZDbcSqLiteStatement.pas
│ ├── ZDbcSqLiteUtils.pas
│ ├── ZDbcStatement.pas
│ └── ZDbcUtils.pas
├── parsesql/
│ ├── ZAdoToken.pas
│ ├── ZGenericSqlAnalyser.pas
│ ├── ZGenericSqlToken.pas
│ ├── ZInterbaseAnalyser.pas
│ ├── ZInterbaseToken.pas
│ ├── ZMySqlAnalyser.pas
│ ├── ZMySqlToken.pas
│ ├── ZOracleAnalyser.pas
│ ├── ZOracleToken.pas
│ ├── ZParseSql.inc
│ ├── ZPostgreSqlAnalyser.pas
│ ├── ZPostgreSqlToken.pas
│ ├── ZScriptParser.pas
│ ├── ZSelectSchema.pas
│ ├── ZSqLiteAnalyser.pas
│ ├── ZSqLiteToken.pas
│ ├── ZSybaseAnalyser.pas
│ └── ZSybaseToken.pas
├── plain/
│ ├── ZPlain.inc
│ ├── ZPlainASAConstants.pas
│ ├── ZPlainASADriver.pas
│ ├── ZPlainAdo.pas
│ ├── ZPlainAdoDriver.pas
│ ├── ZPlainDbLibConstants.pas
│ ├── ZPlainDbLibDriver.pas
│ ├── ZPlainDriver.pas
│ ├── ZPlainFirebirdDriver.pas
│ ├── ZPlainFirebirdInterbaseConstants.pas
│ ├── ZPlainLoader.pas
│ ├── ZPlainMySqlConstants.pas
│ ├── ZPlainMySqlDriver.pas
│ ├── ZPlainOracleConstants.pas
│ ├── ZPlainOracleDriver.pas
│ ├── ZPlainPostgreSqlDriver.pas
│ └── ZPlainSqLiteDriver.pas
├── repl.awk
├── repl.instructions
└── repl.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Uncomment these types if you want even more clean repository. But be careful.
# It can make harm to an existing project source. Read explanations below.
#
# Resource files are binaries containing manifest, project icon and version info.
# They can not be viewed as text or compared by diff-tools. Consider replacing them with .rc files.
#*.res
#
# Type library file (binary). In old Delphi versions it should be stored.
# Since Delphi 2009 it is produced from .ridl file and can safely be ignored.
#*.tlb
#
# Diagram Portfolio file. Used by the diagram editor up to Delphi 7.
# Uncomment this if you are not using diagrams or use newer Delphi version.
#*.ddp
#
# Visual LiveBindings file. Added in Delphi XE2.
# Uncomment this if you are not using LiveBindings Designer.
#*.vlb
#
# Deployment Manager configuration file for your project. Added in Delphi XE2.
# Uncomment this if it is not mobile development and you do not use remote debug feature.
#*.deployproj
#
# Delphi compiler-generated binaries (safe to delete)
*.exe
*.dll
*.bpl
*.bpi
*.dcp
*.so
*.apk
*.drc
*.map
*.dres
*.rsm
*.tds
*.dcu
*.lib
# Delphi autogenerated files (duplicated info)
*.cfg
*Resource.rc
# Delphi local files (user-specific info)
*.local
*.identcache
*.projdata
*.tvsconfig
*.dsk
# Delphi history and backups
__history/
*.~*
# Castalia statistics file
*.stat
# Repository ignore
*.ini
*.zip
backend/logs/*.txt
loc/
test/
frontend/__history/
frontend/logs/
frontend/patches/
*.txaPackage
frontend/profiles/
================================================
FILE: LICENSE.txt
================================================
MOZILLA PUBLIC LICENSE
Version 1.1
---------------
1. Definitions.
1.0.1. "Commercial Use" means distribution or otherwise making the
Covered Code available to a third party.
1.1. "Contributor" means each entity that creates or contributes to
the creation of Modifications.
1.2. "Contributor Version" means the combination of the Original
Code, prior Modifications used by a Contributor, and the Modifications
made by that particular Contributor.
1.3. "Covered Code" means the Original Code or Modifications or the
combination of the Original Code and Modifications, in each case
including portions thereof.
1.4. "Electronic Distribution Mechanism" means a mechanism generally
accepted in the software development community for the electronic
transfer of data.
1.5. "Executable" means Covered Code in any form other than Source
Code.
1.6. "Initial Developer" means the individual or entity identified
as the Initial Developer in the Source Code notice required by Exhibit
A.
1.7. "Larger Work" means a work which combines Covered Code or
portions thereof with code not governed by the terms of this License.
1.8. "License" means this document.
1.8.1. "Licensable" means having the right to grant, to the maximum
extent possible, whether at the time of the initial grant or
subsequently acquired, any and all of the rights conveyed herein.
1.9. "Modifications" means any addition to or deletion from the
substance or structure of either the Original Code or any previous
Modifications. When Covered Code is released as a series of files, a
Modification is:
A. Any addition to or deletion from the contents of a file
containing Original Code or previous Modifications.
B. Any new file that contains any part of the Original Code or
previous Modifications.
1.10. "Original Code" means Source Code of computer software code
which is described in the Source Code notice required by Exhibit A as
Original Code, and which, at the time of its release under this
License is not already Covered Code governed by this License.
1.10.1. "Patent Claims" means any patent claim(s), now owned or
hereafter acquired, including without limitation, method, process,
and apparatus claims, in any patent Licensable by grantor.
1.11. "Source Code" means the preferred form of the Covered Code for
making modifications to it, including all modules it contains, plus
any associated interface definition files, scripts used to control
compilation and installation of an Executable, or source code
differential comparisons against either the Original Code or another
well known, available Covered Code of the Contributor's choice. The
Source Code can be in a compressed or archival form, provided the
appropriate decompression or de-archiving software is widely available
for no charge.
1.12. "You" (or "Your") means an individual or a legal entity
exercising rights under, and complying with all of the terms of, this
License or a future version of this License issued under Section 6.1.
For legal entities, "You" includes any entity which controls, is
controlled by, or is under common control with You. For purposes of
this definition, "control" means (a) the power, direct or indirect,
to cause the direction or management of such entity, whether by
contract or otherwise, or (b) ownership of more than fifty percent
(50%) of the outstanding shares or beneficial ownership of such
entity.
2. Source Code License.
2.1. The Initial Developer Grant.
The Initial Developer hereby grants You a world-wide, royalty-free,
non-exclusive license, subject to third party intellectual property
claims:
(a) under intellectual property rights (other than patent or
trademark) Licensable by Initial Developer to use, reproduce,
modify, display, perform, sublicense and distribute the Original
Code (or portions thereof) with or without Modifications, and/or
as part of a Larger Work; and
(b) under Patents Claims infringed by the making, using or
selling of Original Code, to make, have made, use, practice,
sell, and offer for sale, and/or otherwise dispose of the
Original Code (or portions thereof).
(c) the licenses granted in this Section 2.1(a) and (b) are
effective on the date Initial Developer first distributes
Original Code under the terms of this License.
(d) Notwithstanding Section 2.1(b) above, no patent license is
granted: 1) for code that You delete from the Original Code; 2)
separate from the Original Code; or 3) for infringements caused
by: i) the modification of the Original Code or ii) the
combination of the Original Code with other software or devices.
2.2. Contributor Grant.
Subject to third party intellectual property claims, each Contributor
hereby grants You a world-wide, royalty-free, non-exclusive license
(a) under intellectual property rights (other than patent or
trademark) Licensable by Contributor, to use, reproduce, modify,
display, perform, sublicense and distribute the Modifications
created by such Contributor (or portions thereof) either on an
unmodified basis, with other Modifications, as Covered Code
and/or as part of a Larger Work; and
(b) under Patent Claims infringed by the making, using, or
selling of Modifications made by that Contributor either alone
and/or in combination with its Contributor Version (or portions
of such combination), to make, use, sell, offer for sale, have
made, and/or otherwise dispose of: 1) Modifications made by that
Contributor (or portions thereof); and 2) the combination of
Modifications made by that Contributor with its Contributor
Version (or portions of such combination).
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
effective on the date Contributor first makes Commercial Use of
the Covered Code.
(d) Notwithstanding Section 2.2(b) above, no patent license is
granted: 1) for any code that Contributor has deleted from the
Contributor Version; 2) separate from the Contributor Version;
3) for infringements caused by: i) third party modifications of
Contributor Version or ii) the combination of Modifications made
by that Contributor with other software (except as part of the
Contributor Version) or other devices; or 4) under Patent Claims
infringed by Covered Code in the absence of Modifications made by
that Contributor.
3. Distribution Obligations.
3.1. Application of License.
The Modifications which You create or to which You contribute are
governed by the terms of this License, including without limitation
Section 2.2. The Source Code version of Covered Code may be
distributed only under the terms of this License or a future version
of this License released under Section 6.1, and You must include a
copy of this License with every copy of the Source Code You
distribute. You may not offer or impose any terms on any Source Code
version that alters or restricts the applicable version of this
License or the recipients' rights hereunder. However, You may include
an additional document offering the additional rights described in
Section 3.5.
3.2. Availability of Source Code.
Any Modification which You create or to which You contribute must be
made available in Source Code form under the terms of this License
either on the same media as an Executable version or via an accepted
Electronic Distribution Mechanism to anyone to whom you made an
Executable version available; and if made available via Electronic
Distribution Mechanism, must remain available for at least twelve (12)
months after the date it initially became available, or at least six
(6) months after a subsequent version of that particular Modification
has been made available to such recipients. You are responsible for
ensuring that the Source Code version remains available even if the
Electronic Distribution Mechanism is maintained by a third party.
3.3. Description of Modifications.
You must cause all Covered Code to which You contribute to contain a
file documenting the changes You made to create that Covered Code and
the date of any change. You must include a prominent statement that
the Modification is derived, directly or indirectly, from Original
Code provided by the Initial Developer and including the name of the
Initial Developer in (a) the Source Code, and (b) in any notice in an
Executable version or related documentation in which You describe the
origin or ownership of the Covered Code.
3.4. Intellectual Property Matters
(a) Third Party Claims.
If Contributor has knowledge that a license under a third party's
intellectual property rights is required to exercise the rights
granted by such Contributor under Sections 2.1 or 2.2,
Contributor must include a text file with the Source Code
distribution titled "LEGAL" which describes the claim and the
party making the claim in sufficient detail that a recipient will
know whom to contact. If Contributor obtains such knowledge after
the Modification is made available as described in Section 3.2,
Contributor shall promptly modify the LEGAL file in all copies
Contributor makes available thereafter and shall take other steps
(such as notifying appropriate mailing lists or newsgroups)
reasonably calculated to inform those who received the Covered
Code that new knowledge has been obtained.
(b) Contributor APIs.
If Contributor's Modifications include an application programming
interface and Contributor has knowledge of patent licenses which
are reasonably necessary to implement that API, Contributor must
also include this information in the LEGAL file.
(c) Representations.
Contributor represents that, except as disclosed pursuant to
Section 3.4(a) above, Contributor believes that Contributor's
Modifications are Contributor's original creation(s) and/or
Contributor has sufficient rights to grant the rights conveyed by
this License.
3.5. Required Notices.
You must duplicate the notice in Exhibit A in each file of the Source
Code. If it is not possible to put such notice in a particular Source
Code file due to its structure, then You must include such notice in a
location (such as a relevant directory) where a user would be likely
to look for such a notice. If You created one or more Modification(s)
You may add your name as a Contributor to the notice described in
Exhibit A. You must also duplicate this License in any documentation
for the Source Code where You describe recipients' rights or ownership
rights relating to Covered Code. You may choose to offer, and to
charge a fee for, warranty, support, indemnity or liability
obligations to one or more recipients of Covered Code. However, You
may do so only on Your own behalf, and not on behalf of the Initial
Developer or any Contributor. You must make it absolutely clear than
any such warranty, support, indemnity or liability obligation is
offered by You alone, and You hereby agree to indemnify the Initial
Developer and every Contributor for any liability incurred by the
Initial Developer or such Contributor as a result of warranty,
support, indemnity or liability terms You offer.
3.6. Distribution of Executable Versions.
You may distribute Covered Code in Executable form only if the
requirements of Section 3.1-3.5 have been met for that Covered Code,
and if You include a notice stating that the Source Code version of
the Covered Code is available under the terms of this License,
including a description of how and where You have fulfilled the
obligations of Section 3.2. The notice must be conspicuously included
in any notice in an Executable version, related documentation or
collateral in which You describe recipients' rights relating to the
Covered Code. You may distribute the Executable version of Covered
Code or ownership rights under a license of Your choice, which may
contain terms different from this License, provided that You are in
compliance with the terms of this License and that the license for the
Executable version does not attempt to limit or alter the recipient's
rights in the Source Code version from the rights set forth in this
License. If You distribute the Executable version under a different
license You must make it absolutely clear that any terms which differ
from this License are offered by You alone, not by the Initial
Developer or any Contributor. You hereby agree to indemnify the
Initial Developer and every Contributor for any liability incurred by
the Initial Developer or such Contributor as a result of any such
terms You offer.
3.7. Larger Works.
You may create a Larger Work by combining Covered Code with other code
not governed by the terms of this License and distribute the Larger
Work as a single product. In such a case, You must make sure the
requirements of this License are fulfilled for the Covered Code.
4. Inability to Comply Due to Statute or Regulation.
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Code due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description
must be included in the LEGAL file described in Section 3.4 and must
be included with all distributions of the Source Code. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
5. Application of this License.
This License applies to code to which the Initial Developer has
attached the notice in Exhibit A and to related Covered Code.
6. Versions of the License.
6.1. New Versions.
Netscape Communications Corporation ("Netscape") may publish revised
and/or new versions of the License from time to time. Each version
will be given a distinguishing version number.
6.2. Effect of New Versions.
Once Covered Code has been published under a particular version of the
License, You may always continue to use it under the terms of that
version. You may also choose to use such Covered Code under the terms
of any subsequent version of the License published by Netscape. No one
other than Netscape has the right to modify the terms applicable to
Covered Code created under this License.
6.3. Derivative Works.
If You create or use a modified version of this License (which you may
only do in order to apply it to code which is not already Covered Code
governed by this License), You must (a) rename Your license so that
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
"MPL", "NPL" or any confusingly similar phrase do not appear in your
license (except to note that your license differs from this License)
and (b) otherwise make it clear that Your version of the license
contains terms which differ from the Mozilla Public License and
Netscape Public License. (Filling in the name of the Initial
Developer, Original Code or Contributor in the notice described in
Exhibit A shall not of themselves be deemed to be modifications of
this License.)
7. DISCLAIMER OF WARRANTY.
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
8. TERMINATION.
8.1. This License and the rights granted hereunder will terminate
automatically if You fail to comply with terms herein and fail to cure
such breach within 30 days of becoming aware of the breach. All
sublicenses to the Covered Code which are properly granted shall
survive any termination of this License. Provisions which, by their
nature, must remain in effect beyond the termination of this License
shall survive.
8.2. If You initiate litigation by asserting a patent infringement
claim (excluding declatory judgment actions) against Initial Developer
or a Contributor (the Initial Developer or Contributor against whom
You file such action is referred to as "Participant") alleging that:
(a) such Participant's Contributor Version directly or indirectly
infringes any patent, then any and all rights granted by such
Participant to You under Sections 2.1 and/or 2.2 of this License
shall, upon 60 days notice from Participant terminate prospectively,
unless if within 60 days after receipt of notice You either: (i)
agree in writing to pay Participant a mutually agreeable reasonable
royalty for Your past and future use of Modifications made by such
Participant, or (ii) withdraw Your litigation claim with respect to
the Contributor Version against such Participant. If within 60 days
of notice, a reasonable royalty and payment arrangement are not
mutually agreed upon in writing by the parties or the litigation claim
is not withdrawn, the rights granted by Participant to You under
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
the 60 day notice period specified above.
(b) any software, hardware, or device, other than such Participant's
Contributor Version, directly or indirectly infringes any patent, then
any rights granted to You by such Participant under Sections 2.1(b)
and 2.2(b) are revoked effective as of the date You first made, used,
sold, distributed, or had made, Modifications made by that
Participant.
8.3. If You assert a patent infringement claim against Participant
alleging that such Participant's Contributor Version directly or
indirectly infringes any patent where such claim is resolved (such as
by license or settlement) prior to the initiation of patent
infringement litigation, then the reasonable value of the licenses
granted by such Participant under Sections 2.1 or 2.2 shall be taken
into account in determining the amount or value of any payment or
license.
8.4. In the event of termination under Sections 8.1 or 8.2 above,
all end user license agreements (excluding distributors and resellers)
which have been validly granted by You or any distributor hereunder
prior to termination shall survive termination.
9. LIMITATION OF LIABILITY.
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
10. U.S. GOVERNMENT END USERS.
The Covered Code is a "commercial item," as that term is defined in
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
software" and "commercial computer software documentation," as such
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
all U.S. Government End Users acquire Covered Code with only those
rights set forth herein.
11. MISCELLANEOUS.
This License represents the complete agreement concerning subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. This License shall be governed by
California law provisions (except to the extent applicable law, if
any, provides otherwise), excluding its conflict-of-law provisions.
With respect to disputes in which at least one party is a citizen of,
or an entity chartered or registered to do business in the United
States of America, any litigation relating to this License shall be
subject to the jurisdiction of the Federal Courts of the Northern
District of California, with venue lying in Santa Clara County,
California, with the losing party responsible for costs, including
without limitation, court costs and reasonable attorneys' fees and
expenses. The application of the United Nations Convention on
Contracts for the International Sale of Goods is expressly excluded.
Any law or regulation which provides that the language of a contract
shall be construed against the drafter shall not apply to this
License.
12. RESPONSIBILITY FOR CLAIMS.
As between Initial Developer and the Contributors, each party is
responsible for claims and damages arising, directly or indirectly,
out of its utilization of rights under this License and You agree to
work with Initial Developer and Contributors to distribute such
responsibility on an equitable basis. Nothing herein is intended or
shall be deemed to constitute any admission of liability.
13. MULTIPLE-LICENSED CODE.
Initial Developer may designate portions of the Covered Code as
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
Developer permits you to utilize portions of the Covered Code under
Your choice of the NPL or the alternative licenses, if any, specified
by the Initial Developer in the file described in Exhibit A.
EXHIBIT A -Mozilla Public License.
``The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is ______________________________________.
The Initial Developer of the Original Code is ________________________.
Portions created by ______________________ are Copyright (C) ______
_______________________. All Rights Reserved.
Contributor(s): ______________________________________.
Alternatively, the contents of this file may be used under the terms
of the _____ license (the "[___] License"), in which case the
provisions of [______] License are applicable instead of those
above. If you wish to allow use of your version of this file only
under the terms of the [____] License and not to allow others to use
your version of this file under the MPL, indicate your decision by
deleting the provisions above and replace them with the notice and
other provisions required by the [___] License. If you do not delete
the provisions above, a recipient may use your version of this file
under either the MPL or the [___] License."
[NOTE: The text of this Exhibit A may differ slightly from the text of
the notices in the Source Code files of the Original Code. You should
use the text of this Exhibit A rather than the text found in the
Original Code Source Code for Your Modifications.]
================================================
FILE: README.md
================================================
# smash
A tool for performing automatic conflict resolution between multiple Bethesda Plugin Files for TES and Fallout games.
## explanation
Characters, items, quests, music tracks, leveled lists, weathers, magical effects, etc. are all represented in plugin files as records. When multiple mods modify the same records, only the last loaded mod's changes get used by the game (with some exceptions). This is known as the rule of one. Many plugin patches combine the changes of multiple mods to resolve conflicts, but there is no way to create and distribute patches for every possible combination of conflicting mods. This is where tools like Mator Smash come in. Mator Smash allows for conflict resolution patches to be generated following rules, known as "Smash Settings". This allows users to quickly and efficiently combine the edits of multiple mods.
## intended usage
Use Mator Smash to generate a patch, then verify the changes in the patch in xEdit. Fix any conflicts that were not resolved correctly. Smashed patches should be usable without a manual verification step, but can in certain rare cases lead to crashes/unintended behavior in game. If you run into issues please report them [here](https://github.com/matortheeternal/smash/issues). You can safely disable or delete your smashed patch at any time.
# resources
If you're looking for support or want to contribute, join the [Modding Tools discord server](https://discord.gg/GUfRdpT).
You can find additional information and discussion on the [Nexus Mods](https://www.nexusmods.com/skyrim/mods/90987) mod page, in the [STEP forum topic](http://forum.step-project.com/topic/6936-wip-mator-smash/), and in the [Nexus Mods forum topic](https://forums.nexusmods.com/index.php?/topic/3707015-wip-mator-smash-the-conflict-resolution-revolution/).
================================================
FILE: design/code snippets/GetMasterElement.pas
================================================
{for j := 0 to ElementCount(ae) - 1 do begin
ne := ebi(ae, j);
if (SortKey(ne, false) = sk) then begin
Result := ne;
break;
end;
end;}
{for j := 0 to ElementCount(ae) - 1 do begin
ne := ebi(ae, j);
if (gav(ne) = sk) then begin
Result := ne;
break;
end;
end;}
function ElementByKey(e: IwbElement; key: string; bUseSortKey: boolean): IwbElement;
var
i: Integer;
c: IwbContainerElementRef;
begin
if not Supports(e, IwbContainerElementRef, c) then
exit;
// loop through children elements
for i := 0 to Pred(c.ElementCount) do begin
element := c.Elements[i];
// get sort key if bUseSortKey, else get values key
if bUseSortKey then
eKey := element.SortKey[false]
else
eKey := GetAllValues(element);
// if keys match result is current element
if eKey = key then begin
Result := element;
break;
end;
end;
end;
function GetMasterElement(src, se: IwbElement; dstRec: IwbMainRecord): IwbElement;
var
i: integer;
path, key: string;
mstRec, ovr: IwbMainRecord;
mst: IwbElement;
sorted: boolean;
begin
Result := nil;
mstRec := MasterOrSelf(dstRec);
path := IndexedPath(src);
bSorted := IsSorted(src);
// if sorted, use SortKey, else use GetAllValues
if bSorted then
key := se.SortKey[false]
else
key := GetAllValues(se);
// debug message
if debugGetMaster then
Tracker.Write(' Called GetMasterElement at path '+p+' looking for Key '+key);
// loop from override 0 to the second to last override
// last override is in our patch, we don't want to process that one
for i := 0 to mstRec.OverrideCount - 2 do begin
ovr := mst.Overrides[i];
mst := ElementByIndexedPath[(mstRec, p);
Result := ElementByKey(mst, key, bSorted);
// break if we found a subrecord matching the sortkey
if Result <> nil then
break;
end;
end;
================================================
FILE: design/code snippets/Mator Smash v0.9.pas
================================================
{
Mator Smash v0.9.6
created by matortheeternal
* DESCRIPTION *
This script will make a patch similar to a bashed patch.
}
unit smash;
uses mteFunctions;
const
vs = 'v0.9.6';
settingsPath = scriptsPath + 'smash\settings\';
dashes = '-----------------------------------------------------------';
// these booleans control logging
debugGetMaster = false;
debugArrays = false;
listOverrides = false;
showChanges = false;
showTraversal = false;
showSkips = false;
showTypeStrings = false;
showRecTimes = false;
verbose = false;
disableStyles = false;
// maximum records to be smashed
maxRecords = 100000;
splitChar = '#13';
var
slRecords, slSettings, slOptions, slFiles, slSubrecords,
slGlobalSubrecords, recordTree, subrecordTree, include: TStringList;
lstSettings: TList;
userFile: IInterface;
global_records, global_subrecords, global_recordMode,
global_subrecordMode, global_setting: string;
makeNewLine: boolean;
AssetPath: string;
checkboxImages: TCustomImageList;
{===========================================================}
{ SETTING FORM }
const
cChecked = 1;
cUnChecked = 2;
cPartiallyChecked = 3;
var
sfrm: TForm;
meInclude, meSubrecords: TMemo;
tv: TTreeView;
btnOk, btnCancel: TButton;
{
SetChildren
Sets the StateIndex attribute of all the children of @node
to @state. Uses recursion.
}
procedure SetChildren(node: TTreeNode; state: Integer);
var
tmp: TTreeNode;
begin
// exit if we don't have a node to work with
if not Assigned(node) then exit;
// loop through children setting StateIndex to state
// if child has children, recurse into that child
tmp := node.getFirstChild;
while Assigned(tmp) do begin
tmp.StateIndex := state;
if tmp.HasChildren then
SetChildren(tmp, state);
tmp := tmp.getNextSibling;
end;
end;
{
UpdateParent
Calculates and sets the StateIndex attribute for @node based
on the StateIndex values of its children. Uses recursion to
update parents of the parent that was updated.
}
procedure UpdateParent(node: TTreeNode);
var
tmp: TTreeNode;
state: Integer;
begin
// exit if we don't have a node to work with
if not Assigned(node) then exit;
// parent state is checked if all siblings are checked
state := cChecked;
tmp := node.getFirstChild;
while Assigned(tmp) do begin
if tmp.StateIndex <> cChecked then begin
state := cPartiallyChecked;
break;
end;
tmp := tmp.getNextSibling;
end;
// parent state is unchecked if all siblings are unchecked
if state = cPartiallyChecked then begin
state := cUnChecked;
tmp := node.getFirstChild;
while Assigned(tmp) do begin
if tmp.StateIndex <> cUnChecked then begin
state := cPartiallyChecked;
break;
end;
tmp := tmp.getNextSibling;
end;
end;
// set state, recurse to next parent
node.StateIndex := state;
tmp := node.Parent;
UpdateParent(tmp);
end;
{
CheckBoxManager
Manages checkboxes in the TTreeView. Changes the StateIndex
of the checkbox associated with @node. Uses SetChildren and
UpdateParent. Called by tvClick and tvKeyDown.
}
procedure CheckBoxManager(node: TTreeNode);
begin
// exit if we don't have a node to work with
if not Assigned(node) then exit;
// if unchecked or partially checked, set to checked and
// set all children to checked, update parents
if (node.StateIndex = cUnChecked)
or (node.StateIndex = cPartiallyChecked) then begin
node.StateIndex := cChecked;
UpdateParent(node.Parent);
SetChildren(node, cChecked);
end
// if checked, set to unchecked and set all children to
// unchecked, update parents
else if node.StateIndex = cChecked then begin
node.StateIndex := cUnChecked;
UpdateParent(node.Parent);
SetChildren(node, cUnChecked);
end;
end;
{
tvClick
Event handler for when the user clicks anywhere in the
TreeView. If the user clicks on a checkbox it calls
CheckBoxManager to toggle the state of the selected
checkbox.
}
procedure tvClick(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
HT: THitTests;
begin
HT := tv.GetHitTestInfoAt(X, Y);
if (HT - [htOnStateIcon] <> HT) then
CheckBoxManager(tv.Selected);
end;
{
tvKeyDown
Event handler for when the user presses a key while the
TreeView is focused. If the user presses space we call
CheckBoxManager to toggle the state of the selected
checkbox.
}
procedure tvKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if (Key = VK_SPACE) and Assigned(tv.Selected) then
CheckBoxManager(tv.Selected);
end;
{
tvExpanding
Event handler for when the user expands a node in the
TreeView. If we haven't loaded the subrecords for the
record represented by @node, we call LoadNodes.
}
procedure tvExpanding(Sender: TObject; node: TTreeNode;
var AllowExpansion: Boolean);
var
i: integer;
begin
if not Assigned(node.getFirstChild) then exit;
// if we haven't loaded subrecord data yet, attempt to
// load it from the subrecord stringlist
if node.getFirstChild.Text = 'Elements' then begin
// find record signature in subrecords stringlist
// exit if not found
i := subrecordTree.IndexOf(node.Text);
if i = -1 then exit;
// load nodes from the subrecords stringlist
// starting at the first subrecord
LoadNodes(subrecordTree, tv, node, i + 1, 2);
// delete 'Elements' placeholder node
node.getFirstChild.Delete;
end;
end;
{
LeadingSpaces
Calculates the number of leading spaces in a PChar string
and returns it as an integer.
}
function LeadingSpaces(var s: PChar): integer;
var
i: integer;
begin
Result := 0;
i := 1;
while (true) do begin
if s[i] = ' ' then
Inc(Result)
else
exit;
Inc(i);
end;
end;
{
LoadNodes
Loads nodes from @sl into @tv as children of @node. Starts
at index @i in the stringlist and adds children which have
leading spaces matching @cws. If there are more leading
spaces than @cws, we use recursion to add the list item as
a child of the current list item @curNode. If there are
fewer leading spaces than @cws we exit.
}
procedure LoadNodes(var sl: TStringList; tv: TTreeView; node: TTreeNode;
var i: integer; cws: integer);
var
lws: integer;
p: PChar;
curNode: TTreeNode;
begin
curNode := node;
while (true) do begin
// exit if we reached the end of the stringlist
if i > sl.Count - 1 then exit;
p := sl[i];
lws := LeadingSpaces(p);
// if lws matches cws, add as child of current node
// (we're on the right level)
if lws = cws then begin
curNode := tv.Items.AddChild(node, Trim(sl[i]));
curNode.StateIndex := node.StateIndex;
end
// if leading spaces of the current item exceeds cws,
// recurse to add as child of the last added node
// (we need to go down a level)
else if lws > cws then begin
LoadNodes(sl, tv, curNode, i, lws);
continue;
end
// if cws exceeds lws, exit
// (we need to go up a level)
else
exit;
// go to next item in list
Inc(i);
end;
end;
{
FindNode
Finds a node matching @s as a child of @node.
}
function FindNode(node: TTreeNode; const s: string): TTreeNode;
var
tmp: TTreeNode;
begin
Result := nil;
tmp := node.getFirstChild;
while (Assigned(tmp)) do begin
if (tmp.Text = s) then begin
Result := tmp;
exit;
end;
tmp := tmp.getNextSibling;
end;
end;
{
DisableNodes
Disables nodes from @sl in @tv found as children of @node.
Starts at index @i in the stringlist and locates children
which have leading spaces matching @cws. If there are more
leading spaces than @cws, we use recursion to find the list
item in the current item @curNode. If there are fewer leading
spaces than @cws we exit.
}
procedure DisableNodes(var sl: TStringList; tv: TTreeView; node: TTreeNode;
var i: integer; cws: integer);
var
lws: integer;
p: PChar;
curNode: TTreeNode;
begin
curNode := node;
while (true) do begin
// exit if we reached the end of the stringlist
if i > sl.Count - 1 then exit;
p := sl[i];
lws := LeadingSpaces(p);
// if lws matches cws, find and disable
if lws = cws then begin
curNode := FindNode(node, Trim(sl[i]));
if not Assigned(curNode) then begin
Inc(i);
continue;
end;
if i + 1 = sl.Count then begin
curNode.StateIndex := cUnChecked;
end
else begin
p := sl[i+1];
lws := LeadingSpaces(p);
if lws > cws then begin
tvExpanding(nil, curNode, true);
curNode.StateIndex := cPartiallyChecked;
end
else begin
curNode.StateIndex := cUnChecked;
end;
end;
end
// if leading spaces of the current item exceeds cws,
// recurse to find in the last added node
// (we need to go down a level)
else if lws > cws then begin
DisableNodes(sl, tv, curNode, i, lws);
continue;
end
// if cws exceeds lws, exit
// (we need to go up a level)
else
exit;
// go to next item in list
Inc(i);
end;
end;
{
MakeBold
Changes the style of @lbl to bold.
}
procedure MakeBold(lbl: TLabel);
begin
if not disableStyles then begin
lbl.WordWrap := false;
lbl.Font.Style := lbl.Font.Style + [fsBold];
end;
end;
{
SettingFormResize
Event to fire when the setting form is resized
}
procedure SettingFormResize(Sender: TObject);
begin
tv.Width := sfrm.Width - 48;
tv.Height := sfrm.Height - 155;
btnOk.Top := sfrm.Height - 86;
btnOk.Left := sfrm.Width div 2 - btnOk.Width - 8;
btnCancel.Top := btnOk.Top;
btnCancel.Left := btnOk.Left + btnOk.Width + 16;
end;
{
CreateIncludeList
Recursively traverses a TreeView starting at @node adding node
text properties to @sl, with @depth concatenated before each text
item.
}
procedure CreateIncludeList(var sl: TStringList; node: TTreeNode; depth: string);
var
tmp: TTreeNode;
begin
if (not node.HasChildren) then exit;
tmp := node.getFirstChild;
while (Assigned(tmp)) do begin
if (tmp.StateIndex = cUnChecked) then
sl.Add(depth + tmp.Text)
else if (tmp.HasChildren) and (tmp.StateIndex = cPartiallyChecked) then begin
sl.Add(depth + tmp.Text);
CreateIncludeList(sl, tmp, depth + ' ');
end;
tmp := tmp.getNextSibling;
end;
end;
{
SettingForm
Used to create or edit setting presets.
}
procedure SettingForm(Sender: TObject);
var
lblName, lblRecords, lblSubrecords: TLabel;
edName: TEdit;
ini, template: TMemIni;
usingTemplate: boolean;
caption: string;
node: TTreeNode;
ndx: integer;
begin
// assign template
include := TStringList.Create;
caption := TButton(Sender).Caption;
usingTemplate := caption <> 'New setting';
if lst.ItemIndex > -1 then
template := TMemIniFile(lstSettings[slSettings.IndexOf(lst.Items[lst.ItemIndex])])
else
usingTemplate := false;
sfrm := TForm.Create(nil);
try
// set up form
sfrm.Width := 400;
sfrm.Height := 600;
sfrm.Position := poScreenCenter;
sfrm.Caption := 'Create new Smash Setting';
sfrm.Constraints.MinHeight := 400;
sfrm.Constraints.MinWidth := 286;
// make label and edit for name
lblName := cLabel(sfrm, sfrm, 16, 16, 0, 0, 'Name: ', '');
edName := cEdit(sfrm, sfrm, lblName.Top, lblName.Left + lblName.Width + 8, 0, 200, '', '');
// make tree view
tv := TTreeView.Create(sfrm);
tv.Parent := sfrm;
tv.Left := lblName.Left;
tv.Top := lblName.Top + lblName.Height + 20;
tv.Width := sfrm.Width - 48;
tv.Height := sfrm.Height - 155;
tv.Indent := 19;
tv.ReadOnly := true;
tv.StateImages := checkboxImages;
tv.OnMouseDown := tvClick;
tv.OnKeyDown := tvKeyDown;
tv.OnExpanding := tvExpanding;
// construct ok and cancel buttons
btnOk := TButton.Create(sfrm);
btnOk.Parent := sfrm;
btnOk.Left := sfrm.Width div 2 - btnOk.Width - 8;
btnOk.Top := sfrm.Height - 86;
btnOk.Caption := 'OK';
btnOk.ModalResult := mrOK;
btnCancel := TButton.Create(sfrm);
btnCancel.Parent := sfrm;
btnCancel.Left := btnOk.Left + btnOk.Width + 16;
btnCancel.Top := btnOk.Top;
btnCancel.Caption := 'Cancel';
btnCancel.ModalResult := mrCancel;
// load record nodes
node := tv.Items.Add(nil, 'Records');
if usingTemplate then
node.StateIndex := cChecked
else
node.StateIndex := cUnChecked;
LoadNodes(recordTree, tv, node, 0, 0);
// if using template, load values from it for form
if usingTemplate then begin
edName.Caption := template.ReadString('Setting', 'Name', '');
if caption = 'Copy setting' then begin
sfrm.Caption := 'Copy Smash Setting';
edName.Caption := 'Copy of '+edName.Caption;
end
else if caption = 'Edit setting' then begin
sfrm.Caption := 'Edit Smash Setting';
edName.Enabled := false;
end;
include.LoadFromFile(settingsPath + edName.Caption + '.ini');
ndx := include.IndexOf('[Tree]') + 1;
if (ndx < include.Count) then begin
if (include[ndx] <> '') then begin
DisableNodes(include, tv, node, ndx, 0);
node.StateIndex := cPartiallyChecked;
end;
end;
end;
// set onresize event
sfrm.OnResize := SettingFormResize;
// if user clicks ok, save to ini and update lists
if sfrm.ShowModal = mrOk then begin
ini := TMemIniFile.Create(settingsPath + edName.Caption + '.ini');
ini.WriteString('Setting', 'Name', edName.Caption);
ini.UpdateFile;
include.LoadFromFile(settingsPath + edName.Caption + '.ini');
ndx := include.IndexOf('[Tree]');
if (ndx = -1) then
include.Add('[Tree]')
else begin
Inc(ndx);
while (include.Count > ndx) do
include.Delete(ndx);
end;
CreateIncludeList(include, node, '');
include.SaveToFile(settingsPath + edName.Caption + '.ini');
if (slSettings.IndexOf(edName.Caption) = -1) then begin
lstSettings.Add(ini);
slSettings.Add(edName.Caption);
lst.Items.Add(edName.Caption);
end
else
lstSettings[slSettings.IndexOf(edName.Caption)] := ini;
end;
finally
sfrm.Free;
end;
end;
{===========================================================}
{ SETTING MANAGER FORM }
var
btnDetails, btnEdit, btnCopy, btnDel: TButton;
gear: TPicture;
lst: TListBox;
{
ToggleButtons
Toggles btnEdit, btnCopy, btnDelete.
}
procedure ToggleButtons(Sender: TObject);
var
b: boolean;
begin
b := (TListBox(Sender).ItemIndex > -1);
btnEdit.Enabled := b; btnCopy.Enabled := b; btnDel.Enabled := b;
end;
{
DeleteSetting
Deletes the currently selected setting.
}
procedure DeleteSetting(Sender: TObject);
var
s: string;
begin
if lst.ItemIndex > -1 then begin
s := lst.Items[lst.ItemIndex];
lstSettings.Delete(slSettings.IndexOf(s));
slSettings.Delete(slSettings.IndexOf(s));
lst.Items.Delete(lst.ItemIndex);
lst.ItemIndex := -1;
DeleteFile(settingsPath + s + '.ini');
end;
end;
{
UpdateSettings
Updates the setting comboboxes for OptionsForm
}
procedure UpdateSettings;
var
i, ndx: integer;
cb: TComboBox;
s: string;
begin
for i := 0 to pnlCount - 1 do begin
cb := TComboBox(pnlArray[i].Components[1]);
s := cb.Items[cb.ItemIndex];
cb.Items.Text := slSettings.Text;
if cb.Items.IndexOf(s) > -1 then
cb.ItemIndex := cb.Items.IndexOf(s)
else
cb.ItemIndex := 0;
end;
// update global setting combobox
s := gscb.Items[gscb.ItemIndex];
gscb.Items.Text := slSettings.Text;
if gscb.Items.IndexOf(s) > -1 then
gscb.ItemIndex := gscb.Items.IndexOf(s)
else
gscb.ItemIndex := 0;
end;
{
SettingManager
Used by the user to view, edit, and create settings.
}
procedure SettingManager;
var
ofrm: TForm;
i, h: integer;
btnNew, btnOk : TButton;
begin
ofrm := TForm.Create(nil);
try
ofrm.Caption := 'Advanced Options';
ofrm.Width := 400;
ofrm.Position := poScreenCenter;
ofrm.Height := 300;
h := slSettings.Count * 15 + 85;
if h > 500 then
h := 500;
if h > ofrm.Height then
ofrm.Height := h;
// list box of settings
lst := TListBox.Create(ofrm);
lst.Parent := ofrm;
lst.Top := 8;
lst.Left := 8;
lst.Height := ofrm.Height - 105;
lst.Width := ofrm.Width - 145;
for i := 0 to slSettings.Count - 1 do
lst.Items.Add(slSettings[i]);
lst.OnClick := ToggleButtons;
// new setting button
btnNew := cButton(ofrm, ofrm, 8, lst.Left + lst.Width + 8, 0, 100, 'New setting');
btnNew.OnClick := SettingForm;
// edit setting button
btnEdit := cButton(ofrm, ofrm, btnNew.Top + btnNew.Height + 8, btnNew.Left, 0, 100, 'Edit setting');
btnEdit.OnClick := SettingForm;
btnEdit.Enabled := false;
// copy setting button
btnCopy := cButton(ofrm, ofrm, btnEdit.Top + btnEdit.Height + 8, btnNew.Left, 0, 100, 'Copy Setting');
btnCopy.OnClick := SettingForm;
btnCopy.Enabled := false;
// delete setting button
btnDel := cButton(ofrm, ofrm, btnCopy.Top + btnCopy.Height + 8, btnNew.Left, 0, 100, 'Delete setting');
btnDel.OnClick := DeleteSetting;
btnDel.Enabled := false;
// OK button
btnOk := cButton(ofrm, ofrm, ofrm.Height - 80, ofrm.Width div 2 - 40, 0, 0, 'OK');
btnOk.ModalResult := mrOk;
ofrm.ShowModal;
finally
ofrm.free;
end;
UpdateSettings;
end;
{===========================================================}
{ PLUGIN DETAILS FORM }
{
GetGroupOverrides
}
function GetGroupOverrides(f: IInterface): string;
var
i: integer;
e: IInterface;
begin
for i := 0 to ElementCount(f) - 1 do begin
e := ebi(f, i);
if Signature(e) = 'TES4' then continue;
Result := Result + GroupSignature(e) + ': '+IntToStr(OverrideRecordCount(e))+' overrides'#13#10;
end;
end;
{
PluginDetails
Form which shows advanced details on a plugin
}
procedure PluginDetails(Sender: TObject);
var
f, e: IInterface;
i: integer;
fn, author, records, overrides, desc, masters, groups: string;
pfrm: TForm;
lbl: TLabel;
sb: TScrollBox;
memo: TMemo;
begin
// find file
fn := TLabel(Sender).Caption;
fn := Copy(fn, Pos(']', fn) + 2, Length(fn));
f := FileByName(fn);
// get data
author := geev(ebi(f, 0), 'CNAM');
records := IntToStr(RecordCount(f));
overrides := IntToStr(OverrideRecordCount(f));
desc := geev(ebi(f, 0), 'SNAM');
e := ebn(ebi(f, 0), 'Master Files');
for i := 0 to ElementCount(e) - 1 do
masters := masters + geev(ebi(e, i), 'MAST') + #13#10;
groups := GetGroupOverrides(f);
// display form
pfrm := TForm.Create(nil);
try
pfrm.Caption := fn;
pfrm.Width := 400;
pfrm.Height := 600;
pfrm.Position := poScreenCenter;
lbl := cLabel(pfrm, pfrm, 8, 8, 0, 150, 'Filename:', '');
MakeBold(lbl);
lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, fn, '');
lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Author:', '');
MakeBold(lbl);
lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, author, '');
lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Number of records:', '');
MakeBold(lbl);
lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, records, '');
lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Number of overrides:', '');
MakeBold(lbl);
lbl := cLabel(pfrm, pfrm, lbl.Top, 160, 0, 200, overrides, '');
lbl := cLabel(pfrm, pfrm, lbl.Top + 22, 8, 0, 150, 'Description:', '');
MakeBold(lbl);
memo := cMemo(pfrm, pfrm, lbl.Top + 22, 16, 100, 348, true, true, ssVertical, desc);
lbl := cLabel(pfrm, pfrm, memo.Top + memo.Height + 16, 8, 0, 150, 'Masters:', '');
MakeBold(lbl);
memo := cMemo(pfrm, pfrm, lbl.Top + 22, 16, 100, 348, true, true, ssVertical, masters);
lbl := cLabel(pfrm, pfrm, memo.Top + memo.Height + 16, 8, 0, 150, 'Record groups:', '');
MakeBold(lbl);
memo := cMemo(pfrm, pfrm, lbl.Top + 22, 16, 150, 348, true, true, ssVertical, groups);
pfrm.ShowModal;
finally
pfrm.Free;
end;
end;
{===========================================================}
{ OPTIONS FORM }
var
frm: TForm;
gscb: TComboBox;
pnlArray: Array[0..255] of TPanel;
pnlCount: integer;
{
OptionsForm
Form from which the user can access the setting manager,
plugin details, and set the settings to be used when smashing
the loaded plugins.
}
function OptionsForm: boolean;
var
i, height, m: integer;
btnSmash, btnCancel: TButton;
optionslbl, fnlbl, gslbl: TLabel;
cb: TComboBox;
f: IInterface;
fn, author, s: string;
imgOptions: TImage;
pnl: TPanel;
holder: TObject;
sb: TScrollBar;
begin
Result := false;
frm := TForm.Create(nil);
try
frm.Caption := 'Mator Smash Options';
frm.Width := 550;
frm.Position := poScreenCenter;
frm.Height := 400;
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
fn := GetFileName(f);
author := geev(ebi(f, 0), 'CNAM');
if (Pos(fn, bethesdaFiles) > 0) or (Pos('Mator Smash', author) > 0) then Continue;
Inc(m);
end;
height := m*40 + 170;
if height > (Screen.Height - 100) then begin
frm.Height := Screen.Height - 100;
sb := TScrollBox.Create(frm);
sb.Parent := frm;
sb.Height := Screen.Height - 210;
sb.Width := frm.Width - 20;
sb.Align := alTop;
holder := sb;
end
else begin
frm.Height := height;
holder := frm;
end;
optionslbl := cLabel(frm, holder, 8, 8, 0, 450,
'Set the options you want to use for smashing the following plugins:', '');
pnlCount := 0;
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
fn := GetFileName(f);
author := geev(ebi(f, 0), 'CNAM');
if Pos(fn, bethesdaFiles) > 0 then
continue;
if Pos('Mator Smash', author) > 0 then
continue;
pnlArray[pnlCount] := TPanel.Create(frm);
pnlArray[pnlCount].Parent := holder;
pnlArray[pnlCount].Left := 0;
pnlArray[pnlCount].Top := 30 + pnlCount*40;
pnlArray[pnlCount].Width := holder.Width - 25;
pnlArray[pnlCount].BevelOuter := bvNone;
pnlArray[pnlCount].BevelInner := bvNone; // or bvLowered
pnlArray[pnlCount].BorderStyle := bsNone; // or bsSingle
fnlbl := cLabel(pnlArray[pnlCount], pnlArray[pnlCount], 14, 24, 0, 0, '['+IntToHex(i - 1, 2)+'] '+fn, '');
fnlbl.OnClick := PluginDetails;
MakeBold(fnlbl);
cb := TComboBox.Create(pnlArray[pnlCount]);
cb.Parent := pnlArray[pnlCount];
cb.Style := csDropDownList;
cb.Items := slSettings;
cb.ItemIndex := 0;
if slSettings.IndexOf('default') > -1 then
cb.ItemIndex := slSettings.IndexOf('default');
cb.Top := 12;
cb.Width := 150;
cb.Left := holder.Width - cb.Width - 40;
slFiles.Add(fn);
Inc(pnlCount);
end;
// create global setting controls
gslbl := cLabel(frm, holder, pnlArray[pnlCount - 1].Top + pnlArray[pnlCount - 1].Height + 16,
optionslbl.Left, 0, 70, 'Global setting: ', '');
gscb := TComboBox.Create(frm);
gscb.Parent := holder;
gscb.Top := gslbl.Top;
gscb.Left := gslbl.Left + gslbl.Width + 16;
gscb.Width := 150;
gscb.Style := csDropDownList;
gscb.Items := slSettings;
gscb.ItemIndex := 0;
if slSettings.IndexOf('default') > -1 then
gscb.ItemIndex := slSettings.IndexOf('default');
pnl := TPanel.Create(frm);
pnl.Parent := frm;
pnl.BevelOuter := bvNone;
pnl.Align := alBottom;
pnl.Height := 50;
imgOptions := cImage(pnl, pnl, pnl.Height - 40, frm.Width - 50, 24, 24, gear, 'Advanced Options');
imgOptions.OnClick := SettingManager;
// create ok/cancel buttons
btnSmash := cButton(frm, pnl, pnl.Height - 40, frm.Width div 2 - 88, 0, 0, 'Smash!');
btnSmash.ModalResult := mrOk;
btnCancel := cButton(frm, pnl, btnSmash.Top, btnSmash.Left + btnSmash.Width + 16, 0, 0, 'Cancel');
btnCancel.ModalResult := mrCancel;
if frm.ShowModal = mrOk then begin
for i := 0 to pnlCount - 1 do begin
s := TComboBox(pnlArray[i].Components[1]).Text;
slOptions.Add(s);
end;
global_setting := gscb.Text;
Result := true;
end;
finally
frm.Free;
end;
end;
{===========================================================}
{ SMASHING METHODS }
var
pb: TProgressBar;
memo: TMemo;
lbl: TLabel;
{
LogMessage
Adds @msg to the log stringlist
}
procedure LogMessage(msg: string);
begin
memo.Lines.add(msg);
Application.processmessages;
end;
{
GetMasterElement
Gets the first instance of an element (the master)
}
function GetMasterElement(src, se, dstrec: IInterface): IInterface;
var
i, j, ndx: integer;
p, sk: string;
ovr, ae, ne, mst: IInterface;
sorted: boolean;
begin
Result := nil;
mst := MasterOrSelf(dstrec);
p := IndexedPath(src);
sk := SortKey(se, false);
sorted := not (sk = '');
// if sorted, look for an element matching sort key
if sorted then begin
if debugGetMaster then LogMessage(' Called GetMasterElement at path '+p+' looking for SortKey '+SortKey(se, false));
// loop from override 0 to the second to last override
for i := 0 to OverrideCount(mst) - 2 do begin
ovr := OverrideByIndex(mst, i);
ae := ebp(mst, p);
for j := 0 to ElementCount(ae) - 1 do begin
ne := ebi(ae, j);
if (SortKey(ne, false) = sk) then begin
Result := ne;
break;
end;
end;
// break if we found a subrecord matching the sortkey
if Result <> nil then
break;
end;
end
// if unsorted, look for the element using gav
else begin
sk := gav(se);
if debugGetMaster then LogMessage(' Called GetMasterElement at path '+p+' looking for '+sk);
ae := ebp(mst, p);
for i := 0 to OverrideCount(mst) - 1 do begin
ovr := OverrideByIndex(mst, i);
ae := ebp(ovr, p);
for j := 0 to ElementCount(ae) - 1 do begin
ne := ebi(ae, j);
if (gav(ne) = sk) then begin
Result := ne;
break;
end;
end;
end;
end;
end;
{
nbsOverrideCount
Non-Bethesda Override Count
}
function nbsOverrideCount(r: IInterface): integer;
var
i: integer;
fn: string;
begin
Result := 0;
for i := 0 to OverrideCount(r) - 1 do begin
fn := GetFileName(GetFile(OverrideByIndex(r, i)));
if Pos(fn, bethesdaFiles) = 0 then
Result := Result + 1;
end;
end;
{
BuildSortKeyList
Puts the sort keys of elements in a stringlist
}
procedure BuildSortKeyList(element: IInterface; var sl: TStringList);
var
i, n: integer;
childElement: IInterface;
sk, skAdj: string;
begin
for i := 0 to ElementCount(element) - 1 do begin
childElement := ebi(element, i);
sk := SortKey(childElement, false);
skAdj := sk;
n := 0;
while sl.IndexOf(skAdj) > -1 do begin
Inc(n);
skAdj := sk + '-' + IntTostr(n);
end;
if debugArrays and (n > 0) then LogMessage(' Adjusted SortKey: '+skAdj);
sl.Add(skAdj);
end;
end;
{
MergeSortedArray
Merges sorted array elements
}
procedure MergeSortedArray(mst, src, dst, dstrec: IInterface; depth: string; ini: TMemIniFile);
var
i, m_ndx, s_ndx, d_ndx, n: integer;
me, se, de, ne: IInterface;
slMst, slDst, slSrc: TStringList;
useValues: boolean;
dts, ets, sk: string;
begin
// Step 1: build lists of elements in each array for easy comparison
slMst := TStringList.Create;
slSrc := TStringList.Create;
slDst := TStringList.Create;
slDst.Sorted := true;
BuildSortKeyList(mst, slMst);
BuildSortKeyList(src, slSrc);
BuildSortKeyList(dst, slDst);
// Step 2: Remove elements that are in mst and dst, but missing from src
for i := 0 to slMst.Count - 1 do begin
s_ndx := slSrc.IndexOf(slMst[i]);
d_ndx := slDst.IndexOf(slMst[i]);
if (s_ndx = -1) and (d_ndx > -1) then begin
if debugArrays then LogMessage(' > Removing element '+Path(ebi(dst, d_ndx))+' with key: '+slDst[d_ndx]);
RemoveElement(dst, ebi(dst, d_ndx));
slDst.Delete(d_ndx);
end;
end;
// Step 3: Copy array elements in src that aren't in mst.
for i := 0 to slSrc.Count - 1 do begin
d_ndx := slDst.IndexOf(slSrc[i]);
m_ndx := slMst.IndexOf(slSrc[i]);
se := ebi(src, i);
dts := DefTypeString(se);
ets := ElementTypeString(se);
if (d_ndx = -1) and (m_ndx = -1) then begin
if debugArrays then LogMessage(' > Adding element '+IntToStr(i)+' at '+Path(dst)+' with key: '+slSrc[i]);
ne := ElementAssign(dst, HighInteger, se, false);
if debugArrays then LogMessage(' > '+gav(ne));
slDst.Add(slSrc[i]);
end
// Step 3.5: If array element is in dst and has subelements, traverse it.
else if (d_ndx > -1) and ((dts = 'dtStruct') or (ets = 'etSubRecordArray')) then begin
if showTraversal then LogMessage(' > Traversing element '+Path(se)+' with key: '+slSrc[i]);
if showTraversal and debugArrays then LogMessage(' > Source Element: '+gav(se)+
#13#10' > Destination Element: '+gav(ebi(dst, d_ndx)));
try
rcore(se, GetMasterElement(src, se, dstrec), ebi(dst, d_ndx), dstrec, depth + ' ', ini);
except on x : Exception do begin
LogMessage(' !! rcore exception: '+x.Message);
end;
end;
end
else if (d_ndx > -1) and (ets = 'etSubRecordStruct') then begin
if showTraversal then LogMessage(' > Traversing element '+Path(se)+' with key: '+slSrc[i]);
if showTraversal and debugArrays then LogMessage(' > Source Element: '+gav(se)+
#13#10' > Destination Element: '+gav(ebi(dst, d_ndx)));
try
rcore(se, GetMasterElement(src, se, dstrec), ebi(dst, d_ndx), dstrec, depth + ' ', ini);
except on x : Exception do begin
LogMessage(' !! rcore exception: '+x.Message);
end;
end;
end;
end;
// Step 4: Free lists.
slMst.Free;
slSrc.Free;
slDst.Free;
end;
{
BuildElementList
Puts the values of elements in a stringlist
}
procedure BuildElementList(element: IInterface; var sl: TStringList);
var
i, n: integer;
childElement: IInterface;
values, valuesAdj: string;
begin
for i := 0 to ElementCount(element) - 1 do begin
childElement := ebi(element, i);
values := gav(childElement);
valuesAdj := values;
n := 0;
while (sl.IndexOf(valuesAdj) > -1) do begin
Inc(n);
valuesAdj := values + IntToStr(n);
end;
sl.Add(valuesAdj);
end;
end;
{
MergeUnsortedArray
Merges unsorted array elements
}
procedure MergeUnsortedArray(mst, src, dst, dstrec: IInterface; depth: string; ini: TMemIniFile);
var
i, m_ndx, s_ndx, d_ndx: integer;
me, se, de: IInterface;
slMst, slSrc, slDst: TStringList;
useValues: boolean;
dts, ets: string;
begin
// Step 1: build lists of elements in each array for easy comparison
slMst := TStringList.Create;
slSrc := TStringList.Create;
slDst := TStringList.Create;
BuildElementList(mst, slMst);
BuildElementList(src, slSrc);
BuildElementList(dst, slDst);
// Step 2: Remove elements that are in mst and dst, but missing from src
for i := 0 to slMst.Count - 1 do begin
s_ndx := slSrc.IndexOf(slMst[i]);
d_ndx := slDst.IndexOf(slMst[i]);
if (s_ndx = -1) and (d_ndx > -1) then begin
if debugArrays then LogMessage(' > Removing element at '+Path(dst)+' with values: '+slMst[i]);
RemoveElement(dst, d_ndx);
slDst.Delete(d_ndx);
end;
end;
// Step 3: Copy array elements in src that aren't in mst or dst
for i := 0 to slSrc.Count - 1 do begin
d_ndx := slDst.IndexOf(slSrc[i]);
m_ndx := slMst.IndexOf(slSrc[i]);
se := ebi(src, i);
//if debugArrays then LogMessage('Looking to copy '+slSrc[i]);
if (m_ndx = -1) and (d_ndx = -1) then begin
if debugArrays then LogMessage(' > Adding element at '+Path(dst)+' with values: '+slSrc[i]);
ElementAssign(dst, HighInteger, se, false);
slDst.Add(slSrc[i]);
end;
end;
// Step 4: Free lists.
slMst.Free;
slSrc.Free;
slDst.Free;
end;
{
ListHasMatch
Check if a list has a matching subrecord
}
function ListHasMatch(var sl: TStringList; input: string): boolean;
var
i: integer;
ex: string;
begin
Result := false;
for i := 0 to sl.Count - 1 do begin
ex := sl[i];
if (Pos('*', ex) > 0) then begin
SetChar(ex, Pos('*', ex), '');
if (Pos(ex, input) > 0) then begin
Result := true;
exit;
end;
end
else if (ex = input) then begin
Result := true;
exit;
end;
end;
end;
{
SkipRecord
Returns whether or not a record should be skipped
}
function SkipRecord(rec: IInterface; records, recordMode: string): boolean;
var
s: string;
begin
s := Signature(rec);
Result := ((Pos(s, records) > 0) and (recordMode = '0'))
or ((Pos(s, records) = 0) and (recordMode = '1'))
or ((Pos(s, global_records) > 0) and (global_recordMode = '0'))
or ((Pos(s, global_records) = 0) and (global_recordMode = '1'))
end;
{
SkipSubrecord
Check if a subrecord should be skipped
}
function SkipSubrecord(subrecord: IInterface; ini: TMemIniFile): boolean;
var
subrecords, subrecordMode, subrecordPath: string;
match, globalMatch: boolean;
begin
// load subrecord settings
subrecordMode := ini.ReadString('Setting', 'subrecordMode', '0');
// path string
subrecordPath := Path(subrecord);
// result boolean
match := ListHasMatch(slSubrecords, subrecordPath);
globalMatch := ListHasMatch(slGlobalSubrecords, subrecordPath);
Result := ((subrecordMode = '0') and (match))
or ((subrecordMode = '1') and not (match))
or ((global_subrecordMode = '0') and (globalMatch))
or ((global_subrecordMode = '1') and not (globalMatch));
end;
{
AddElementsToList
Adds children elements to a stringlist
}
procedure AddElementsToList(element: IInterface; var sl: TStringList);
var
i: integer;
childElement: IInterface;
begin
for i := 0 to ElementCount(element) - 1 do begin
childElement := ebi(element, i);
sl.Add(Name(childElement));
end;
end;
{
IsValueElement
Checks if an element is a value element
}
function IsValueElement(elementType: string): boolean;
begin
Result := (elementType = 'dtInteger')
or (elementType = 'dtFloat')
or (elementType = 'dtUnion')
or (elementType = 'dtByteArray')
or (elementType = 'dtString')
or (elementType = 'dtLString')
or (elementType = 'dtLenString');
end;
{
rcore
Recursively Copy Overridden Elements
}
procedure rcore(src, mst, dst, dstrec: IInterface; depth: string; ini: TMemIniFile);
var
i, j, k, max: integer;
se, me, de, sse, mse, kse, kme, kde, xse: IInterface;
mv, sv, ets, dts, cts, cas, ctsrc, subrecords, subrecordMode: string;
diff: TRecordDiff;
slDst, slMst: TStringList;
skip: boolean;
begin
// initialize stringlists
slDst := TStringList.Create; // list of destination elements
slMst := TStringList.Create; // list of master elements
// copy elements from source to destination if missing
AddElementsToList(dst, slDst);
AddElementsToList(mst, slMst);
for i := 0 to ElementCount(src) - 1 do begin
se := ebi(src, i);
// if the element isn't in the destination record
// and wasn't in the master record, copy it to the destination
// if it isn't in the destination but is in the master it means
// that it was deleted and shouldn't be copied.
if (slDst.IndexOf(Name(se)) = -1)
and (slMst.IndexOf(Name(se)) = -1) then
wbCopyElementToRecord(se, dst, false, true);
end;
// loop through subelements
i := 0;
j := 0;
while i < ElementCount(src) do begin
// assign source, destination, master elements
// ensure index out of bounds doesn't occur by not reassigning
// past the last element
if i < ElementCount(src) then
se := ebi(src, i);
if j < ElementCount(dst) then
de := ebi(dst, j);
me := ebn(mst, Name(se));
// DefType and ElementType strings
ets := ElementTypeString(se);
dts := DefTypeString(se);
// skip record header, copy record flags
if Name(se) = 'Record Header' then begin
wbCopyElementToRecord(ebp(se, 'Record Flags'), dst, false, true);
Inc(i);
Inc(j);
continue;
end;
// skip subrecordsToSkip
skip := SkipSubrecord(se, ini);
if skip then begin
if showSkips then LogMessage(' Skipping '+Path(se));
Inc(i);
Inc(j);
continue;
end;
// debug messages
if showTraversal then LogMessage(' '+Path(se));
if showTypeStrings then LogMessage(' ets: '+ets+' dts: '+dts);
// if destination element doesn't match source element
if (Name(se) <> Name(de)) then begin
// if we're not at the end of the destination elements
// proceed to next destination element
// else proceed to next source element
if (j < ElementCount(dst)) then
Inc(j)
else
Inc(i);
continue;
end;
// deal with subrecord arrays
if (ets = 'etSubRecordArray') or (dts = 'dtArray') then begin
// if sorted, deal with sorted array
if IsSorted(se) then begin
if debugArrays then LogMessage(' Sorted array found: '+Path(se));
try
MergeSortedArray(me, se, de, dstrec, depth, ini);
except on x : Exception do
LogMessage(' !! MergeSortedArray exception: '+x.Message);
end;
end
// else deal with unsorted etSubRecordArray
else if (ets = 'etSubRecordArray') then begin
if debugArrays then LogMessage(' Unsorted etSubRecordArray found: '+Path(se));
try
MergeUnsortedArray(me, se, de, dstrec, depth, ini);
except on x : Exception do
LogMessage(' !! MergeUnsortedArray exception: '+x.Message);
end;
end
// else deal with unsorted dtArray
else begin
if debugArrays then LogMessage(' Unsorted dtArray found: '+Path(se));
try
MergeUnsortedArray(me, se, de, dstrec, depth, ini);
//rcore(se, me, de, dstrec, depth + ' ', ini);
except on x : Exception do
LogMessage(' !! MergeUnsortedArray exception: '+x.Message);
end;
end;
end
// else recurse deeper
else if (ElementCount(se) > 0) and (dts <> 'dtInteger') then begin
try
rcore(se, me, de, dstrec, depth + ' ', ini);
except on x : Exception do
LogMessage(' !! rcore exception in element '+Path(se)+': '+x.Message);
end;
end
// else copy element if value differs from master
else if IsValueElement(dts) and (GetEditValue(se) <> GetEditValue(me)) then begin
if (Assigned(me)) and showChanges then begin
if (not showTraversal) then LogMessage(' '+Path(se));
LogMessage(' > Found differing values: '+GetEditValue(se)+' and '+GetEditValue(me));
end;
// try to copy element value to destination element from source element
try
SetEditValue(de, GetEditValue(se));
except on x : Exception do
LogMessage(' !! Copy element value exception: '+x.Message);
end;
end;
// proceed to next subelement
Inc(i);
Inc(j);
end;
slDst.Free;
slMst.Free;
end;
{
IsSmashedPatch
Checks if @f is a smashed patch
}
function IsSmashedPatch(f: IInterface): boolean;
var
author: string;
begin
author := geev(ElementByIndex(f, 0), 'CNAM');
Result := (Pos('Mator Smash', author) = 1);
end;
{
SmashRecord
Smashes @rec into @smashFile.
}
procedure SmashRecord(rec, smashFile: IInterface);
var
i: integer;
fn, author: string;
f, ovr, mr: IInterface;
ini: TMemIniFile;
begin
// loop through record's overrides
for i := 0 to OverrideCount(rec) - 1 do begin
ovr := OverrideByIndex(rec, i);
f := GetFile(ovr);
fn := GetFileName(f);
// skip overrides in bethesda files
if (Pos(fn, bethesdaFiles) > 0) then
continue;
// skip overrides in smashed patches
if (IsSmashedPatch(f)) then
continue;
// skip ctIdenticalToMaster overrides
if (ConflictThisForMainRecord(ovr) = ctIdenticalToMaster) then
continue;
// if master record is not assigned, copy winning override to smashed patch
if (not Assigned(mr)) then begin
try
mr := wbCopyElementToFile(WinningOverride(ovr), smashFile, false, true);
except on x: Exception do
LogMessage(' !! Exception copying record '+Name(rec)+' : '+x.Message);
end;
end;
// look up setting for this file
try
ini := TMemIniFile(lstSettings[slSettings.IndexOf(slOptions[slFiles.IndexOf(fn)])]);
except on x : Exception do
LogMessage('Setting lookup exception : '+x.Message);
end;
// recursively copy overriden elements
try
if makeNewLine then LogMessage('');
LogMessage('Smashing record '+Name(rec)+' from file: '+fn);
slSubrecords.Text := StringReplace(ini.ReadString('Setting', 'subrecords', ''), '#13', #13, [rfReplaceAll]);
rcore(ovr, rec, mr, mr, ' ', ini);
except on x : Exception do
LogMessage(' !! Exception smashing record '+Name(rec)+' : '+x.Message);
end;
end;
end;
{===========================================================}
{ MAIN EXECUTION }
{
ShowDetails
Enables the visibilty of the TMemo log
}
procedure ShowDetails;
begin
frm.Height := 600;
frm.Position := poScreenCenter;
memo.Height := frm.Height - 150;
btnDetails.Visible := false;
memo.Visible := true;
end;
{
InitializeSettings
Loads settings from files
}
procedure InitializeSettings;
var
i: integer;
ini: TMemIniFile;
s: string;
info: TSearchRec;
begin
// create lists
slSettings := TStringList.Create;
lstSettings := TList.Create;
// load settings
SetCurrentDir(settingsPath);
if FindFirst(settingsPath+'*.ini', faAnyFile, info) = 0 then begin
repeat
lstSettings.Add(TMemIniFile.Create(settingsPath + info.Name));
until FindNext(info) <> 0;
end;
// add setting strings
for i := 0 to lstSettings.Count - 1 do begin
s := TMemIniFile(lstSettings[i]).ReadString('Setting', 'Name', '');
slSettings.Add(s);
end;
end;
{
FreeMemory
Frees memory used by script
}
procedure FreeMemory;
begin
gear.Free; slOptions.Free; slFiles.Free; slSettings.Free;
lstSettings.Free;
end;
{
Initialize
Load assets, settings, display forms, show progress bar, perform
main smashing procedure.
}
function Initialize: integer;
var
f, r: IInterface;
i, j, k: integer;
fn, rn, records, recordMode, logFileName, fdt: string;
ini: TMemIniFile;
tStart, tRec: TDateTime;
diff: double;
pic: TPicture;
bmpChecked, bmpUnChecked, bmpPChecked: TBitmap;
begin
// load tree stringlists
AssetPath := ScriptsPath + 'smash\assets\';
recordTree := TStringList.Create;
recordTree.LoadFromFile(AssetPath + 'RecordTree.txt');
subrecordTree := TStringList.Create;
subrecordTree.LoadFromFile(AssetPath + 'SubrecordTree.txt');
include := TStringList.Create;
// load checkbox images
checkboxImages := TCustomImageList.Create(nil);
pic := TPicture.Create;
bmpChecked := TBitmap.Create;
bmpUnChecked := TBitmap.Create;
bmpPChecked := TBitmap.Create;
pic.LoadFromFile(AssetPath + 'Check.bmp');
bmpChecked.SetSize(17, 17);
bmpChecked.Canvas.Draw(0, 0, pic.Graphic);
pic.LoadFromFile(AssetPath + 'UnCheck.bmp');
bmpUnChecked.SetSize(17, 17);
bmpUnChecked.Canvas.Draw(0, 0, pic.Graphic);
pic.LoadFromFile(AssetPath + 'PartialCheck.bmp');
bmpPChecked.SetSize(17, 17);
bmpPChecked.Canvas.Draw(0, 0, pic.Graphic);
checkboxImages.Add(bmpChecked, nil);
checkboxImages.Add(bmpChecked, nil);
checkboxImages.Add(bmpUnChecked, nil);
checkboxImages.Add(bmpPChecked, nil);
// track time
tStart := Now;
// stringlist creation
slOptions := TStringList.Create;
slFiles := TStringList.Create;
slSubrecords := TStringList.Create;
slGlobalSubrecords := TStringList.Create;
makeNewLine := showSkips or showTraversal or debugGetMaster or debugArrays
or showChanges or showTypeStrings or showRecTimes;
// load gui elements
gear := TPicture.Create;
gear.LoadFromFile(AssetPath + 'gear.png');
// load setting files
InitializeSettings;
// set up for saving log
ForceDirectories(ScriptsPath + '\smash\logs');
fdt := FormatDateTime('mmddyy_hhnnss', Now);
logFileName := ScriptsPath + '\smash\logs\smash' + fdt + '.txt';
// initial options form
if OptionsForm then begin
frm := TForm.Create(nil);
try
frm.Caption := 'Mator Smash!';
frm.Width := 700;
frm.Position := poScreenCenter;
frm.Height := 150;
// make progress label
lbl := cLabel(frm, frm, 20, 20, 30, 600, 'Initializing...', '');
// make progress bar
pb := TProgressBar.Create(frm);
pb.Parent := frm;
pb.Top := 40;
pb.Left := 20;
pb.Width := frm.Width - 55;
pb.Height := 20;
pb.Step := 1;
pb.Min := 0;
pb.Position := 0;
// make log memo
memo := cMemo(frm, frm, 70, 20, 0, pb.Width, false, true, ssBoth, '');
memo.Visible := false;
// make details button
btnDetails := cButton(frm, frm, pb.Top + pb.Height + 8, pb.Left, 0, 100, 'Show Details');
btnDetails.OnClick := ShowDetails;
// display form, initial logging messages
frm.Show;
application.processmessages;
LogMessage(dashes);
LogMessage('Mator Smash '+vs+': Makes a smashed patch.');
LogMessage(dashes);
// create stringlists
slRecords := TStringList.Create;
// load global settings
ini := TMemIniFile(lstSettings[slSettings.IndexOf(global_setting)]);
global_records := StringReplace(ini.ReadString('Setting', 'records', ''), splitChar, #13#10, [rfReplaceall]);
global_recordMode := ini.ReadString('Setting', 'recordMode', '0');
global_subrecords := StringReplace(ini.ReadString('Setting', 'subrecords', ''), splitChar, #13#10, [rfReplaceall]);
global_subrecordMode := ini.ReadString('Setting', 'subrecordMode', '0');
slGlobalSubrecords.Text := global_subrecords;
// see if a smashed patch is loaded
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
// if smashed patch found, break
if (IsSmashedPatch(f)) then begin
userFile := f;
break;
end;
end;
// make userFile if not found
lbl.Caption := 'Assigning smashed patch.';
application.processmessages;
if not Assigned(userFile) then
userFile := AddNewFile;
if not Assigned(userFile) then begin
LogMessage('Smashed patch not assigned, terminating script');
FreeMemory;
frm.Free;
Result := -1;
exit;
end;
// set userFile author to Mator Smash
lbl.Caption := 'Adding masters to smashed patch.';
application.processmessages;
seev(ebi(userFile, 0), 'CNAM', 'Mator Smash '+vs);
// add masters to userFile
for i := 0 to FileCount - 3 do begin
f := FileByLoadOrder(i);
if (IsSmashedPatch(f)) then
break;
fn := GetFileName(f);
AddMasterIfMissing(userFile, fn);
end;
// loop through all loaded files
k := 0;
tRec := Now;
for i := 0 to FileCount - 1 do begin
f := FileByIndex(i);
fn := GetFileName(f);
// skip bethesda files, we're not patching them
if Pos(fn, bethesdaFiles) > 0 then
continue;
// if smashed patch found, break
if (IsSmashedPatch(f)) then
break;
// build list of records with multiple overrides
lbl.Caption := 'Processing '+fn;
LogMessage('Processing '+fn);
application.processmessages;
// load ini settings
ini := TMemIniFile(lstSettings[slSettings.IndexOf(slOptions[k])]);
records := StringReplace(ini.ReadString('Setting', 'records', ''), splitChar, #13#10, [rfReplaceAll]);
recordMode := ini.ReadString('Setting', 'recordMode', '0');
// loop through records
for j := 0 to RecordCount(f) - 1 do begin
r := MasterOrSelf(RecordByIndex(f, j));
if (OverrideCount(r) <= 1) then
continue;
// skip records according to ini settings
if SkipRecord(r, records, recordMode) then
continue;
rn := Name(r);
if (nbsOverrideCount(r) > 1) then
if (ConflictThisForMainRecord(WinningOverride(r)) <> ctOverride) then
if slRecords.IndexOf(rn) = -1 then begin
slRecords.AddObject(rn, TObject(r));
end;
end;
Inc(k);
end;
diff := (Now - tRec) * 86400;
LogMessage(FormatFloat('0.###', diff) + ' seconds spent processing records.');
// test list of records
if listOverrides then begin
LogMessage('');
for i := 0 to slRecords.Count - 1 do begin
r := ObjectToElement(slRecords.Objects[i]);
LogMessage(slRecords[i]+' ('+IntToStr(OverrideCount(r))+' overrides)');
for j := 0 to OverrideCount(r) - 1 do
LogMessage(' Override #'+IntToStr(j)+': '+GetFileName(GetFile(OverrideByIndex(r, j))));
end;
end;
// smash records that have been overridden multiple times
lbl.Caption := 'Smashing records (1/'+IntToStr(slRecords.Count)+')';
application.processmessages;
pb.Max := slRecords.Count;
LogMessage('');
for i := 0 to slRecords.Count - 1 do begin
tRec := Now;
if i = maxRecords then break;
// smash record
r := ObjectToElement(slRecords.Objects[i]);
SmashRecord(r, userFile);
// update label, print debug message to log after smashing record
lbl.Caption := 'Smashing records ('+IntToStr(i + 2)+'/'+IntToStr(slRecords.Count)+')';
pb.Position := pb.Position + 1;
if showRecTimes then begin
diff := (Now - tRec) * 86400;
LogMessage(' '+FormatFloat('0.###', diff) + 's');
end;
application.processmessages;
end;
// sort and clean masters
SortMasters(userFile);
CleanMasters(userFile);
// finishing messages
lbl.Caption := 'All done.';
LogMessage(#13#10+dashes);
LogMessage('Smashing complete. '+IntToStr(RecordCount(userfile))+' records smashed.');
diff := (Now - tStart) * 86400;
LogMessage('Completed in ' + FormatFloat('0.###', diff) + ' seconds.');
memo.Lines.SaveToFile(logFileName);
application.processmessages;
if (memo.Visible) then begin
frm.Visible := false;
frm.ShowModal;
end;
except on x : Exception do begin
// smash failed
LogMessage(#13#10'Smash failed. Exception: '+x.Message);
memo.Lines.SaveToFile(logFileName);
pb.Position := 0;
lbl.Caption := 'Smash Failed. Exception: '+x.Message;
if not memo.Visible then ShowDetails;
frm.Visible := false;
frm.ShowModal;
Application.processmessages;
end;
end;
frm.Free;
end;
// free memory
FreeMemory;
// call RemoveFilter() to update TES5Edit GUI
try
RemoveFilter();
except on Exception do
AddMessage(#13#10'You''re not using the latest version of xEdit, so the script couldn''t update the GUI.');
AddMessage('Right click in the plugin view and click "Remove Filter" to update the GUI manually.');
end;
end;
end.
================================================
FILE: design/code snippets/better build algorithm.pas
================================================
procedure LoadElementData(var sl: TStringList; container: IwbContainerElementRef);
var
innerContainer: IwbContainerElementRef;
element: IwbElement;
begin
// loop through container's elements
for i := 0 to Pred(container.ElementCount) do begin
element := container.Elements[i];
//if bOverridesOnly and (ConflictThis(element) = ctIdenticalToMaster) then
//continue;
index := sl.IndexOf(element.Name);
// create new element name item if missing
if index = -1 then
index := sl.Add(element.Name);
// traverse children of element, if it has any
if Supports(element, IwbContainerElementRef, innerContainer) then
if innerContainer.ElementCount > 0 then begin
if not Assigned(sl.Objects[index]) then
sl.Objects[index] := TStringList.Create;
LoadElementData(TStringList(sl.Objects[index]), innerContainer);
end;
end;
end;
procedure LoadRecordData(var sl: TStringList; f: IwbFile);
var
i, index: Integer;
container: IwbContainerElementRef;
rec: IwbMainRecord;
begin
// loop through file's records
for i := 0 to Pred(f.RecordCount) do begin
rec := f.Records[i];
// skip excluded signatures
if HasSignature(rec.Signature, excludedSignatures) then
continue;
// skip non-override records
if bOverridesOnly and not IsOverride(rec) then
continue;
index := sl.IndexOf(rec.Signature);
// add new record signature item if missing
if index = -1 then
index := sl.AddObject(rec.Signature, TStringList.Create);
if Supports(rec, IwbContainerElementRef, container) then
LoadElementData(TStringList(sl.Objects[index]), container);
end;
end;
procedure StringsToNodes(node: TTreeNode; var sl: TStringList);
var
child: TTreeNode;
i: Integer;
begin
for i := 0 to Pred(sl.Count) do begin
child := TreeView.Items.AddChild(node, sl[i]);
child.Data := TElementData.Create(0, false, false, false);
if Assigned(sl.Objects[i]) then
StringsToNodes(child, TStringList(sl.Objects[i]));
end;
end;
procedure TTreeThread.Execute;
var
i: Integer;
plugin: TPlugin;
begin
// ?
// BODY
sl := TStringList.Create;
sl.Sorted := true;
for i := 0 to Pred(pluginsToHandle.Count) do begin
plugin := TPlugin(pluginsToHandle[i]);
LoadRecordData(sl, plugin._File);
end;
rootNode := TreeView.Items.Add(nil, 'Records');
StringsToNodes(rootNode, sl);
//?
end;
function GetConflictThis(element: IwbElement): TConflictThis;
var
mainRecord, master, winning: IwbMainRecord;
begin
mainRecord := element.ContainingMainRecord;
if mainRecord.ConflictPriority = cpIgnore then
Result := ctIgnored
else if mainRecord.OverrideCount = 0 then
Result := ctOnlyOne
else begin
master := mainRecord.Master;
winning := mainRecord.WinningOverride;
masterElement := master.ElementByPath(element.Path);
winningElement := winning.ElementByPath(element.Path);
end;
end;
================================================
FILE: design/notes/algorithm problems.txt
================================================
1. Elements with the same name
================================================
FILE: design/notes/handling.txt
================================================
Things to handle: ignoring deletions, treat as single entity, priority, linking
Ignoring deletions:
When applied to an element, ignore deletions in any of its children elements.
-- boolean set to rcore
-- leads us to not call "delete elements if missing"
-- passed to HandleArray
Treat as single entity:
When applied to an element, any change in that its children's values leads us to copy the entire element to replace the destination element.
-- boolean set to rcore
-- rcore made into a function that returns true whenever a change occurs
-- rcore doesn't call CopyElementValue when a value is different, simply returning true instead
-- HandleArray also made into a function that returns true whenever a change occurs
-- Array handlers return true when they detect an element has been added/deleted/changed
Priority:
Overrides load order on a per-element basis. When priority for an element in a record in a file exceeds the priority of the same element in other files we use that element in destination record. (remove?)
Linking:
================================================
FILE: design/notes/high level design.txt
================================================
Smash
Q: Do we want profiles?
A: Yes, because a user may have multiple load orders or games they want to use smash with.
Q: Do we want a backend?
A: Yes. We want to serve up smash settings, plugin action recommendations, and program updates.
Q: What will be the main actions of the user within the program?
A: Create a new smashed patch, view/edit smash settings, view a plugin's record makeup, adjust program settings, update the program, download new smash settings, view the help file, submit smash settings, submit plugin action recommendations, build smashed patches, delete smashed patches, rebuild smashed patches, ...
Q: What attributes will a smashed patch have?
A: Plugins, plugin, date built, name, filename, smash setting, status, hashes, fails, files.
Q: What attributes with a smash setting have?
A: A tree of records/subrecord options (process [boolean], treat as single entity [boolean], priority [byte], preserve deletions [boolean]), applicable plugin makeup (record group breakdown), hash, and a name. All smash settings will be inclusive.
Q: What functionality will smash patch generation make use of?
A:
- Recursive traversal of records and subrecords
- Record and subrecord skipping based on smash setting
- Single-entity subrecord handling
- Sorted array handling
- Unsorted array handling
- Record/subrecord priority
- Record/subrecord preserve deletions option
- Subrecord/record priority handling
- Subrecord linking (possibly)
Q: What information should we expose on plugins and their record makeup?
A: What record groups are in the plugin. How many records are in each record group. The breakdown of new records/override records in the plugin. The breakdown of new records/overrides in each record group. A plugin dependency tree. A breakdown of all record conflicts in the user's load order/between a selected set of plugins. A breakdown of the elements that conflict in the user's load order/between a selected set of plugins.
Q: What attributes will a plugin recommendation have?
A: Plugin filename, plugin hash, smash setting name, smash setting hash.
Q: How will setting recommendations be computed?
A: Each setting will be compared against the plugin to see how many of the conflicts from the plugin it takes care of, and how well it matches the plugin's record makeup.
================================================
FILE: design/notes/linking explanation.txt
================================================
1. we have a set of plugins
2. each plugin has a smash setting
3. each smash setting has a definition for certain records
4. each record definition has a node for each element
5. we can link a node in a record definition to another node
--
If a element's value changes in a record in a file, and another element is linked to that element, the element that's linked will be copied from the record we're processing to the patch (if it exists).
MASTER: R2: R3: R4: SMASHED RECORD:
A: 1 A: 2 A: 1 A: 1 A: 1
B: 2 B: 2 B: 2 B: 2 B: 2
C: 3 C: 4 C: 5 C: 3 C: 5
LINK A to C
Whenever C changes, copy A
================================================
FILE: design/notes/todos 1024.txt
================================================
1. Plugin recommendations "dictionary"
2. Plugin information form (and on main form?)
3. Backend
================================================
FILE: frontend/MatorSmash.dpr
================================================
{*******************************************************************************
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
*******************************************************************************}
program MatorSmash;
{$R 'smash.res' 'smash.rc'}
uses
Forms,
Dialogs,
Controls,
SysUtils,
// lib\mte
CRC32 in '..\lib\mte\CRC32.pas',
mteBase in '..\lib\mte\mteBase.pas',
mteChangeLogForm in '..\lib\mte\mteChangeLogForm.pas',
mteHelpers in '..\lib\mte\mteHelpers.pas',
mteLogger in '..\lib\mte\mteLogger.pas',
mteLogging in '..\lib\mte\mteLogging.pas',
mtePluginSelectionForm in '..\lib\mte\mtePluginSelectionForm.pas',
mteProgressForm in '..\lib\mte\mteProgressForm.pas',
mteTaskHandler in '..\lib\mte\mteTaskHandler.pas',
RttiIni in '..\lib\mte\RttiIni.pas',
RttiJson in '..\lib\mte\RttiJson.pas',
RttiTranslation in '..\lib\mte\RttiTranslation.pas',
W7Taskbar in '..\lib\mte\W7Taskbar.pas',
// lib\xedit
wbBSA in '..\lib\xedit\wbBSA.pas',
wbDefinitionsFNV in '..\lib\xedit\wbDefinitionsFNV.pas',
wbDefinitionsFO3 in '..\lib\xedit\wbDefinitionsFO3.pas',
wbDefinitionsFO4 in '..\lib\xedit\wbDefinitionsFO4.pas',
wbDefinitionsTES3 in '..\lib\xedit\wbDefinitionsTES3.pas',
wbDefinitionsTES4 in '..\lib\xedit\wbDefinitionsTES4.pas',
wbDefinitionsTES5 in '..\lib\xedit\wbDefinitionsTES5.pas',
wbHelpers in '..\lib\xedit\wbHelpers.pas',
wbImplementation in '..\lib\xedit\wbImplementation.pas',
wbInterface in '..\lib\xedit\wbInterface.pas',
wbLocalization in '..\lib\xedit\wbLocalization.pas',
wbSort in '..\lib\xedit\wbSort.pas',
wbStreams in '..\lib\xedit\wbStreams.pas',
// Smash
msConfiguration in 'msConfiguration.pas',
msCore in 'msCore.pas',
msLoader in 'msLoader.pas',
msConflict in 'msConflict.pas',
msChoicePanel in 'msChoicePanel.pas',
msSmash in 'msSmash.pas',
msAlgorithm in 'msAlgorithm.pas',
msProfileForm in 'msProfileForm.pas' {ProfileForm},
msProfilePanel in 'msProfilePanel.pas',
msSmashForm in 'msSmashForm.pas' {SmashForm},
msThreads in 'msThreads.pas',
msOptionsForm in 'msOptionsForm.pas' {OptionsForm},
msSplashForm in 'msSplashForm.pas' {SplashForm},
msEditForm in 'msEditForm.pas' {EditForm},
msSettingsManager in 'msSettingsManager.pas' {SettingsManager},
msPluginSelectionForm in 'msPluginSelectionForm.pas' {MiniPluginSelectionForm},
msConflictForm in 'msConflictForm.pas' {ConflictForm},
msTagManager in 'msTagManager.pas' {TagManager},
msTagHelper in 'msTagHelper.pas' {TagHelper};
{$R *.res}
{$MAXSTACKSIZE 2097152}
const
IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;
{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}
var
bProfileProvided, bUseUTF8: boolean;
sParam, sProfile, sPath: string;
i: Integer;
aSettings: TSettings;
begin
// set important vars
SysUtils.FormatSettings.DecimalSeparator := '.';
Application.HintHidePause := 8000;
//ReportMemoryLeaksOnShutdown := true;
PathList.Values['ProgramPath'] := ExtractFilePath(ParamStr(0));
// get current profile if profile switch provided
for i := 1 to ParamCount do begin
sParam := ParamStr(i);
if sParam = '-profile' then
sProfile := ParamStr(i + 1);
if sParam = '-utf8' then
wbStringEncoding := seUTF8;
end;
bProfileProvided := sProfile <> '';
sPath := Format('%sprofiles\%s\settings.ini', [ProgramPath, sProfile]);
if bProfileProvided and FileExists(sPath) then begin
aSettings := TSettings.Create;
TRttiIni.Load(sPath, aSettings);
CurrentProfile := TProfile.Create(aSettings.profile);
CurrentProfile.gameMode := aSettings.gameMode;
CurrentProfile.gamePath := aSettings.gamePath;
aSettings.Free;
end;
// initialize application
Application.Initialize;
ForceDirectories(PathList.Values['ProgramPath'] + 'profiles');
LoadSettings;
LoadStatistics;
// have user select game mode
if not bProfileProvided then begin
ProfileForm := TProfileForm.Create(nil);
if not (ProfileForm.ShowModal = mrOk) then
exit;
ProfileForm.Free;
end;
// run main application
Application.Title := 'Mator Smash';
Application.CreateForm(TSmashForm, SmashForm);
Application.CreateForm(TProfileForm, ProfileForm);
Application.CreateForm(TOptionsForm, OptionsForm);
Application.CreateForm(TSplashForm, SplashForm);
Application.CreateForm(TEditForm, EditForm);
Application.CreateForm(TSettingsManager, SettingsManager);
Application.CreateForm(TMiniPluginSelectionForm, MiniPluginSelectionForm);
Application.CreateForm(TConflictForm, ConflictForm);
Application.CreateForm(TTagManager, TagManager);
Application.CreateForm(TTagHelper, TagHelper);
Application.Run;
end.
================================================
FILE: frontend/MatorSmash.dproj
================================================
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{12317C9C-736E-45A4-8CB7-E43FF92DD93C}</ProjectGuid>
<MainSource>MatorSmash.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config>
<AppType>Application</AppType>
<FrameworkType>VCL</FrameworkType>
<DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
<ProjectVersion>13.4</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
<TargetedPlatforms>1</TargetedPlatforms>
<Platform>Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='DebugLite' or '$(Cfg_4)'!=''">
<Cfg_4>true</Cfg_4>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_UsePackage>vcl;rtl;vclx;vclactnband;xmlrtl;VclSmp;vclimg;svnui;svn;bdertl;TeeUI;TeeDB;Tee;vcldb;dbrtl;vcldbx;vcltouch;dsnap;dsnapcon;vclib;ibxpress;adortl;IndyCore;IndySystem;IndyProtocols;inet;intrawebdb_110_150;Intraweb_110_150;vclie;websnap;webdsnap;inetdb;inetdbbde;inetdbxpress;soaprtl;vclribbon;dbexpress;DbxCommonDriver;DataSnapIndy10ServerTransport;DataSnapProviderClient;DataSnapClient;dbxcds;DbxClientDriver;DataSnapServer;AzureCloud;DBXInterBaseDriver;DBXMySQLDriver;DBXFirebirdDriver;DBXSybaseASEDriver;DBXSybaseASADriver;DBXOracleDriver;DBXMSSQLDriver;DBXInformixDriver;DBXDb2Driver</DCC_UsePackage>
<DCC_UnitSearchPath>..\lib\Imaging\ZLib;..\lib\abbrevia\source;..\lib\Imaging;..\lib\xedit;..\lib\mte;..\lib\superobject;..\lib\xedit\zlib;..\lib\xedit\lz4;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<DCC_SYMBOL_DEPRECATED>false</DCC_SYMBOL_DEPRECATED>
<DCC_WIDECHAR_REDUCED>false</DCC_WIDECHAR_REDUCED>
<DCC_SYMBOL_PLATFORM>false</DCC_SYMBOL_PLATFORM>
<DCC_UNIT_PLATFORM>false</DCC_UNIT_PLATFORM>
<DCC_COMBINING_SIGNED_UNSIGNED>false</DCC_COMBINING_SIGNED_UNSIGNED>
<Icon_MainIcon>TES5Edit_Icon.ico</Icon_MainIcon>
<DCC_IMPLICIT_STRING_CAST>false</DCC_IMPLICIT_STRING_CAST>
<DCC_COMPARING_SIGNED_UNSIGNED>false</DCC_COMPARING_SIGNED_UNSIGNED>
<Manifest_File>None</Manifest_File>
<VerInfo_Locale>3081</VerInfo_Locale>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<DCC_Namespace>Vcl;Vcl.Imaging;Vcl.Touch;Vcl.Samples;Vcl.Shell;System;Xml;Data;Datasnap;Web;Soap;Winapi;FMX;System.Win;$(DCC_Namespace)</DCC_Namespace>
<DCC_E>false</DCC_E>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_F>false</DCC_F>
<DCC_S>false</DCC_S>
<DCC_N>false</DCC_N>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
<DCC_Define>DEBUG;NX_EXCEPTION_LOG_IN_APP_FOLDER;$(DCC_Define)</DCC_Define>
<DCC_MapFile>3</DCC_MapFile>
<ILINK_MapFileType>DetailedSegments</ILINK_MapFileType>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_4)'!=''">
<DCC_ExeOutput>.\DebugLite</DCC_ExeOutput>
<DCC_Define>DEBUG;NX_EXCEPTION_LOG_IN_APP_FOLDER;LiteVersion;$(DCC_Define)</DCC_Define>
<DCC_MapFile>3</DCC_MapFile>
<ILINK_MapFileType>DetailedSegments</ILINK_MapFileType>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_IOChecking>false</DCC_IOChecking>
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_AssertionsAtRuntime>false</DCC_AssertionsAtRuntime>
<DCC_ImportedDataReferences>false</DCC_ImportedDataReferences>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="MatorSmash.dpr">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<RcCompile Include="smash.rc">
<ContainerId>RC</ContainerId>
<ContainerId>RC</ContainerId>
<Form>smash.res</Form>
</RcCompile>
<DCCReference Include="..\lib\mte\CRC32.pas"/>
<DCCReference Include="..\lib\mte\mteBase.pas"/>
<DCCReference Include="..\lib\mte\mteChangeLogForm.pas"/>
<DCCReference Include="..\lib\mte\mteHelpers.pas"/>
<DCCReference Include="..\lib\mte\mteLogger.pas"/>
<DCCReference Include="..\lib\mte\mteLogging.pas"/>
<DCCReference Include="..\lib\mte\mtePluginSelectionForm.pas"/>
<DCCReference Include="..\lib\mte\mteProgressForm.pas"/>
<DCCReference Include="..\lib\mte\mteTaskHandler.pas"/>
<DCCReference Include="..\lib\mte\RttiIni.pas"/>
<DCCReference Include="..\lib\mte\RttiJson.pas"/>
<DCCReference Include="..\lib\mte\RttiTranslation.pas"/>
<DCCReference Include="..\lib\mte\W7Taskbar.pas"/>
<DCCReference Include="..\lib\xedit\wbBSA.pas"/>
<DCCReference Include="..\lib\xedit\wbDefinitionsFNV.pas"/>
<DCCReference Include="..\lib\xedit\wbDefinitionsFO3.pas"/>
<DCCReference Include="..\lib\xedit\wbDefinitionsFO4.pas"/>
<DCCReference Include="..\lib\xedit\wbDefinitionsTES3.pas"/>
<DCCReference Include="..\lib\xedit\wbDefinitionsTES4.pas"/>
<DCCReference Include="..\lib\xedit\wbDefinitionsTES5.pas"/>
<DCCReference Include="..\lib\xedit\wbHelpers.pas"/>
<DCCReference Include="..\lib\xedit\wbImplementation.pas"/>
<DCCReference Include="..\lib\xedit\wbInterface.pas"/>
<DCCReference Include="..\lib\xedit\wbLocalization.pas"/>
<DCCReference Include="..\lib\xedit\wbSort.pas"/>
<DCCReference Include="..\lib\xedit\wbStreams.pas"/>
<DCCReference Include="msConfiguration.pas"/>
<DCCReference Include="msCore.pas"/>
<DCCReference Include="msLoader.pas"/>
<DCCReference Include="msConflict.pas"/>
<DCCReference Include="msChoicePanel.pas"/>
<DCCReference Include="msSmash.pas"/>
<DCCReference Include="msAlgorithm.pas"/>
<DCCReference Include="msProfileForm.pas">
<Form>ProfileForm</Form>
</DCCReference>
<DCCReference Include="msProfilePanel.pas"/>
<DCCReference Include="msSmashForm.pas">
<Form>SmashForm</Form>
</DCCReference>
<DCCReference Include="msThreads.pas"/>
<DCCReference Include="msOptionsForm.pas">
<Form>OptionsForm</Form>
</DCCReference>
<DCCReference Include="msSplashForm.pas">
<Form>SplashForm</Form>
</DCCReference>
<DCCReference Include="msEditForm.pas">
<Form>EditForm</Form>
</DCCReference>
<DCCReference Include="msSettingsManager.pas">
<Form>SettingsManager</Form>
</DCCReference>
<DCCReference Include="msPluginSelectionForm.pas">
<Form>MiniPluginSelectionForm</Form>
</DCCReference>
<DCCReference Include="msConflictForm.pas">
<Form>ConflictForm</Form>
</DCCReference>
<DCCReference Include="msTagManager.pas">
<Form>TagManager</Form>
</DCCReference>
<DCCReference Include="msTagHelper.pas">
<Form>TagHelper</Form>
</DCCReference>
<None Include="ModelSupport_MatorSmash\default.txvpck"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="DebugLite">
<Key>Cfg_4</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType>VCLApplication</Borland.ProjectType>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">MatorSmash.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">True</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">1</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">True</VersionInfo>
<VersionInfo Name="PreRelease">True</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1033</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.1.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName">Mator Smash</VersionInfoKeys>
<VersionInfoKeys Name="ProductVersion">1.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments">created by matortheeternal</VersionInfoKeys>
</VersionInfoKeys>
<Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcboffice2k150.bpl">Embarcadero C++Builder Office 2000 Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\bcbofficexp150.bpl">Embarcadero C++Builder Office XP Servers Package</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dcloffice2k150.bpl">Microsoft Office 2000 Sample Automation Server Wrapper Components</Excluded_Packages>
<Excluded_Packages Name="$(BDSBIN)\dclofficexp150.bpl">Microsoft Office XP Sample Automation Server Wrapper Components</Excluded_Packages>
</Excluded_Packages>
<Parameters_Win32/>
</Delphi.Personality>
<Platforms>
<Platform value="Win64">False</Platform>
<Platform value="Win32">True</Platform>
</Platforms>
<ModelSupport>True</ModelSupport>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
</Project>
================================================
FILE: frontend/MatorSmash.mes
================================================
[GeneralSettings]
MesVersion=4
HandleExceptions=0
LinkInCode=1
AppendMapFileToBinary=1
NoOwnMadExceptSettings=0
CheckFileCrc=1
CheckForFrozenMainThread=0
FreezeTimeout=60000
ReportLeaks=0
WindowsLogo=0
CrashOnBuffer=0
CrashOnUnderrun=0
AutomaticallySaveBugReport=1
AutoSaveBugReportIfNotSent=0
AutomaticallyMailBugReport=0
AutoMailProgressBox=0
CopyBugReportToClipboard=0
SuspendAllRunningThreads=0
ShowPleaseWaitBox=0
PleaseWaitIcon=plwait1
AutomaticallyContinueApplication=1
AutomaticallyRestartApplication=0
AutomaticallyCloseApplication=0
SendInBackground=0
SendHelper=196608
Send32Icon=send321
UploadViaHttp=0
HttpServer=
HttpSsl=0
HttpPort=0
HttpAccount=
HttpPassword=
UploadToFogBugz=0
UploadToBugZilla=0
UploadToMantis=0
BugTrackerAccount=
BugTrackerPassword=
BugTrackerProject=
BugTrackerArea=
BugTrackerAssignTo=
MailAsSmtpServer=0
MailAsSmtpClient=0
SmtpServer=
SmtpSsl=0
SmtpTls=0
SmtpPort=0
SmtpAccount=
SmtpPassword=
MailViaMapi=0
MailViaMailto=0
MailAddress=
BugReportFile=bugreport.txt
AttachBugReport=0
AttachBugReportFile=1
DeleteBugReportFile=1
BugReportSendAs=bugreport.txt
BugReportZip=
ScreenShotDepth=0
ScreenShotAppOnly=0
ScreenShotSendAs=screenshot.png
ScreenShotZip=
AdditionalAttachments=
AppendBugReports=1
BugReportFileSize=100000
DontSaveDuplicateExceptions=1
DontSaveDuplicateFreezings=1
DuplicateExceptionDefinition=1
DuplicateFreezeDefinition=2
ShowExceptionBox=1
OkBtnText=&OK
DetailsBtnText=&Details
PleaseWaitTitle=Information
PleaseWaitText=Please wait a moment...
BugTrackerTitle=%25appname%25, %25exceptMsg%25
BugTrackerDescr=error details: %0d%0a%25errorDetails%25
MailSubject=bug report
MailBody=please find the bug report attached
SendBoxTitle=Sending bug report...
PrepareAttachMsg=Preparing attachments...
MxLookupMsg=Searching for mail server...
ConnectMsg=Connecting to server...
SendMailMsg=Sending mail...
FieldsMsg=Setting fields...
SendAttachMsg=Sending attachments...
SendFinalizeMsg=Finalizing...
MailFailureMsg=Sorry, sending the bug report didn't work.
VersionVariable=
[ExceptionBox]
ShowButtonMailBugReport=0
ShowButtonSaveBugReport=0
ShowButtonPrintBugReport=0
ShowButtonShowBugReport=1
ShowButtonContinueApplication=1
ShowButtonRestartApplication=1
ShowButtonCloseApplication=1
IconButtonSendBugReport=send1
IconButtonSaveBugReport=save1
IconButtonPrintBugReport=print1
IconButtonShowBugReport=show1
IconButtonContinueApplication=continue1
IconButtonCantContinueApplication=cantContinue1
IconButtonRestartApplication=restart1
IconButtonCloseApplication=close1
FocusedButton=4
SendAssistant=SendAssistant
SaveAssistant=SaveAssistant
PrintAssistant=PrintAssistant
AutomaticallyShowBugReport=0
NoOwnerDrawButtons=0
BigExceptionIcon=big1
TitleBar=%25appname%25
ExceptionMessage=An error occurred in the application.
FrozenMessage=The application seems to be frozen.
BitFaultMsg=The file "%25modname%25" seems to be corrupt!
MailBugReportText=send bug report
SaveBugReportText=save bug report
PrintBugReportText=print bug report
ShowBugReportText=show bug report
ContinueApplicationText=continue application
RestartApplicationText=restart application
CloseApplicationText=close application
[BugReport]
ListThreads=1
ListModules=1
ListHardware=1
ShowCpuRegisters=1
ShowStackDump=1
Disassembly=1
HideUglyItems=0
ShowRelativeAddrs=1
ShowRelativeLines=1
FormatDisassembly=0
LimitDisassembly=5
EnabledPlugins=modules|processes|hardware
[Filters]
Filter1ExceptionClasses=
Filter1DontCreateBugReport=0
Filter1DontCreateScreenshot=0
Filter1DontSuspendThreads=0
Filter1DontCallHandlers=0
Filter1ShowBox=3
Filter1Assis=
Filter2ExceptionClasses=
Filter2DontCreateBugReport=0
Filter2DontCreateScreenshot=0
Filter2DontSuspendThreads=0
Filter2DontCallHandlers=0
Filter2ShowBox=0
Filter2Assis=
GeneralDontCreateBugReport=0
GeneralDontCreateScreenshot=0
GeneralDontSuspendThreads=0
GeneralDontCallHandlers=0
GeneralShowBox=0
GeneralAssis=
[Assistants]
Assistant1=SendAssistant|Send Assistant|ContactForm|DetailsForm|ScrShotForm
Assistant2=SaveAssistant|Save Assistant|ContactForm|DetailsForm
Assistant3=PrintAssistant|Print Assistant|ContactForm|DetailsForm
Forms1=TPF0%0eTMEContactForm%0bContactForm%07Message%0c%13%00%00%00Contact Information%08MinWidth%04%00%00%00%00%08OnAction%0c%1b%00%00%00madExcept.HandleContactForm%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c%0a%00%00%00your name:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%08NameEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%09%0aOutputName%0c%0c%00%00%00contact name%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%08INVLabel%06Label2%07Caption%0c%0b%00%00%00your email:%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%09EmailEdit%07Colored%09%07Enabled%09%05Lines%04%01%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00contact email%0aOutputType%07%09nvoHeader%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%0bINVCheckBox%08MemCheck%07Caption%0c%0b%00%00%00remember me%07Checked%08%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%00
Forms2=TPF0%0eTMEDetailsForm%0bDetailsForm%07Message%0c%0d%00%00%00Error Details%08MinWidth%04%00%00%00%00%08OnAction%0c%00%00%00%00%05Timer%04%00%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%08INVLabel%06Label1%07Caption%0c,%00%00%00what were you doing when the error occurred?%07Enabled%09%07Spacing%04%00%00%00%00%00%00%07INVEdit%0bDetailsMemo%07Colored%09%07Enabled%09%05Lines%04%09%00%00%00%08Optional%08%0aOutputName%0c%0d%00%00%00error details%0aOutputType%07%0dnvoOwnSection%07Spacing%04%00%00%00%00%04Text%0c%00%00%00%00%05Valid%09%00%00%00
Forms3=TPF0%0eTMEScrShotForm%0bScrShotForm%0dActiveControl%07%0bContinueBtn%07Message%0c%18%00%00%00Screenshot Configuration%08MinWidth%04%00%00%00%00%08OnAction%0c%1e%00%00%00madExcept.HandleScreenshotForm%05Timer%04%fa%00%00%00%00%09INVButton%0bContinueBtn%07Caption%0c%08%00%00%00Continue%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%07SkipBtn%07Caption%0c%04%00%00%00Skip%07Enabled%08%0bNoOwnerDraw%08%07Visible%09%00%00%09INVButton%09CancelBtn%07Caption%0c%06%00%00%00Cancel%07Enabled%09%0bNoOwnerDraw%08%07Visible%09%00%00%0bINVCheckBox%0bAttachCheck%07Caption%0c%25%00%00%00attach a screenshot to the bug report%07Checked%09%07Enabled%09%0aOutputName%0c%00%00%00%00%07Spacing%04%00%00%00%00%00%00%08INVImage%0aScrShotImg%06Border%09%09Clickable%09%07Enabled%09%04File%0c%00%00%00%00%06Height%04%00%00%00%00%07Spacing%04%00%00%00%00%05Width%04%00%00%00%00%00%00%08INVLabel%06Label1%07Caption%0c%15%00%00%00(click to edit image)%07Enabled%09%07Spacing%04%00%00%00%00%00%00%00
================================================
FILE: frontend/ModelSupport_MatorSmash/MatorSmash/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="b4zfh5af0zf_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="ea9vm1284dq_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msEditForm/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="njkyjunm3h_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msFrontend/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="n0j337jkpef_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msOptionsForm/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="z6ar60bu6om_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msProfileForm/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="y0bo0tytf3p_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msProfilePanel/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="ac7klwk840k_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msSmashForm/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="d40chv15btm_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msSplashForm/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="xigiykmxj3j_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/ModelSupport_MatorSmash/msThreads/default.txvpck
================================================
<?xml version="1.0" encoding="utf-8"?>
<nodeSet version="1.0">
<view uin="y6gq3u7hleh_v">
<property name="$defaultDiagram" value="true" />
<property name="$metaclass" value="Package Diagram" />
<property name="$name" value="default" />
</view>
</nodeSet>
================================================
FILE: frontend/lang/english.lang
================================================
{ TSmashForm }
{ ## QuickBar ## }
msMain_QuickButton_Hint=Quick patch|Apply Smash.All to loaded plugins and #13#10generate a smashed patch.#13#10
msMain_NewButton_Hint=Create new smashed patch|Make a new empty smashed patch.
msMain_BuildButton_Hint=Build patches|
msMain_ManageButton_Hint=Manage smash settings|Click here to manage smash settings.
msMain_OptionsButton_Hint=Options|Change the options that control how the #13#10program runs.#13#10
{ #### DYNAMIC #### }
msMain_NoPatches=There aren't any patches to build or rebuild.
msMain_BuildPatches_Loader=You can't build patches until the background #13#10loader is done.#13#10
msMain_BuildAllPatches=Builds all patches that are ready to be built or #13#10rebuilt.#13#10
{ ## Main Panel ## }
{ ## Details Panel ## }
msMain_DetailsLabel_Caption=Details
msMain_DetailsCopyToClipboardItem_Caption=Copy to clipboard
{ ## Plugins Tab ## }
msMain_PluginsTabSheet_Caption=Plugins
msMain_PluginsListView_Column0=Index
msMain_PluginsListView_Column1=Filename
msMain_PluginsListView_Column2=Setting
msMain_PluginsListView_Column3=Patch
{ #### DYNAMIC #### }
msMain_PluginDetails=Plugin Details
msMain_Filename=Filename
msMain_Hash=Hash
msMain_FileSize=File Size
msMain_DateModified=Date Modified
msMain_NumRecords=Number of records
msMain_NumOverrides=Number of overrides
msMain_Author=Author
msMain_Description=Description
msMain_Masters=Masters
msMain_ClearTags=Are you sure you want to clear tags from these plugins?
{ ## Plugins Popup Menu ## }
msMain_NewPatchItem_Caption=<New Patch>
msMain_OpenPluginLocationItem_Caption=Open plugin location
msMain_AddToPatchItem_Caption=Add to patch
msMain_ManageTagsItem_Caption=Manage Tags
msMain_SmashSettingItem_Caption=Smash setting
{ ## Patches Tab ## }
msMain_PatchesTabSheet_Caption=Patches
msMain_PatchesListView_Column0=Index
msMain_PatchesListView_Column1=Name
msMain_PatchesListView_Column2=Filename
msMain_PatchesListView_Column3=Size
msMain_PatchesListView_Column4=Date built
{ #### DYNAMIC #### }
msMain_PatchDetails=Patch Details
msMain_Status=Status
msMain_PatchName=Patch name
msMain_PluginCount=Plugin count
msMain_DateBuilt=Date built
msMain_Plugins=Plugins
msMain_Fails=Fails
msMain_TooManyFails=Too many fails to display.
msMain_DeletePatches=Are you sure you want to delete these patches?
{ ## Patches Popup Menu ## }
msMain_ToggleRebuildItem_Caption=Toggle rebuild status
msMain_OpenInExplorerItem_Caption=Open in explorer
{ ## Plugins Submenu ## }
msMain_MoveItem_Caption=Move
msMain_UpItem_Caption=Up
msMain_DownItem_Caption=Down
msMain_ToTopItem_Caption=To top
msMain_ToBottomItem_Caption=To bottom
{ #### DYNAMIC #### }
msMain_BuildPatch=Build patch
msMain_RebuildPatch=Rebuild patch
msMain_BuildPatches=Build patches
msMain_RebuildPatches=Rebuilds patches
{ ## Log Tab ## }
msMain_LogTabSheet_Caption=Log
{ #### DYNAMIC #### }
msMain_AppDetails=Application Details
msMain_Application=Application
msMain_Author=Author
msMain_Version=Version
msMain_DateBuilt=Date built
msMain_GameMode=Game mode
msMain_Language=Language
msMain_TimesRun=Times run
msMain_PatchesBuilt=Patches built
msMain_PluginsSmashed=Plugins smashed
msMain_SettingsSubmitted=Smash settings submitted
msMain_RecsSubmitted=Recommendations submitted
msMain_Website=Website
msMain_ApiCredits=API Credits
msMain_xEditVersion=xEdit Version
msMain_xEditCredits=xEdit Credits
msMain_Testers=Testers
msMain_Translators=Translators
msMain_LoadException=Exception Loading Plugins
msMain_PluginsNotLoaded=Due to an exception, not all of your plugins #13#10have been loaded. You can still use the program. #13#10See the log tab for more info.#13#10
msMain_Enable=Enable
msMain_Disable=Disable
msMain_AutoScroll=Autoscroll
{ ## Log Popup Menu ## }
msMain_FilterGroupItem_Caption=Filter group
msMain_FilterLabelItem_Caption=Filter label
msMain_CopyToClipboardItem_Caption=Copy to clipboard
msMain_SaveAndClearItem_Caption=Save and clear
msMain_ToggleAutoScrollItem_Caption=Disable auto scroll
{ TOptionsForm }
mpOpt_btnCancel_Caption=Cancel
mpOpt_btnOK_Caption=OK
{ ## General Tab ## }
mpOpt_GeneralTabSheet_Caption=General
mpOpt_gbLanguage_Caption=Language
mpOpt_lblLanguage_Caption=Current languge
mpOpt_gbStyle_Caption=Style
mpOpt_kbSimpleDictionary_Caption=Simple dictionary view
mpOpt_kbSimplePlugins_Caption=Simple plugins list
{ ## Patching Tab ## }
mpOpt_PatchingTabSheet_Caption=Patching
mpOpt_lblDestinationDirectory_Caption=Patch destination directory
mpOpt_gbDebug_Caption=Debug
mpOpt_gbOther_Caption=Other Options
{ ## Advanced Tab ## }
mpOpt_AdvancedTabSheet_Caption=Advanced
mpOpt_lblCurrentProfile_Caption=Current profile
mpOpt_gbLogging_Caption=Logging
mpOpt_lblClientColor_Caption=Client
mpOpt_lblGeneralColor_Caption=General
mpOpt_lblLoadColor_Caption=Load
mpOpt_lblPluginColor_Caption=Plugin
mpOpt_lblErrorColor_Caption=Errors
mpOpt_lblTemplate_Caption=Template
mpOpt_lblSample_Caption=Sample
{ TSettingsManager }
{ ## Settings ## }
msSet_gbFiltering_Caption=Filtering options
msSet_lvSettings_Column0=Name
msSet_lvSettings_Column1=Records
msSet_btnSave_Caption=Save
msSet_btnDiscard_Caption=Discard
{ ## Settings Popup Menu ## }
msSet_NewSettingItem_Caption=New setting
msSet_CloneSettingItem_Caption=Clone setting
msSet_CombineSettingsItem_Caption=Combine settings
msSet_EditSettingItem_Caption=Edit setting
msSet_DeleteSettingItem_Caption=Delete setting
{ ## Details ## }
msSet_lblName_Caption=Name
msSet_lblColor_Caption=Color
msSet_lblDescription_Caption=Description
msSet_lblTree_Caption=Tree
{ ## Tree Popup Menu ## }
msSet_ToggleNodesItem_Caption=Toggle nodes
msSet_IgnoreDeletionsItem_Caption=Toggle ignore deletions
msSet_SingleEntityItem_Caption=Toggle treat as single entity
msSet_PruneNodesItem_Caption=Prune nodes
msSet_PreserveDeletionsItem_Caption=Toggle preserve deletions
{ TTagManager }
msTagM_Caption=Manage Tags - %s
{ ## General ## }
msTagM_lblDescription_Caption=Description
msTagM_btnAdd_Caption=Add Tags
msTagM_btnRemove_Caption=Remove Tags
msTagM_btnClear_Caption=Clear Tags
msTagM_btnReset_Caption=Reset Tags
msTagM_btnApply_Caption=Apply
msTagM_btnCancel_Caption=Cancel
msTagM_kbCombine_Caption=Apply combined setting
{ TTagHelper }
msTagH_btnCancel_Caption=Cancel
msTagH_btnOK_Caption=OK
{ #### DYNAMIC #### }
msTagH_AddTags=Add Tags
msTagH_RemoveTags=Remove Tags
msTagH_PromptAdd=Check the tags you want to add
msTagH_PromptRemove=Check the tags you want to remove
{ TProgressForm }
{ #### DYNAMIC #### }
msProg_Closing=Closing
msProg_Smashing=Smashing Patches
msProg_DoneBuilding=Done smashing patches
msProg_BuildingTree=Building tree
================================================
FILE: frontend/msAlgorithm.pas
================================================
unit msAlgorithm;
interface
uses
SysUtils, Classes,
// superobject
superobject,
// mte units
mteHelpers, mteTracker, mteBase,
// ms units
msCore, msConfiguration,
// xEdit components
wbInterface, wbImplementation;
procedure CopyLinkedElement(srcCont, dstCont: IwbContainerElementRef;
eLink: string; obj: ISuperObject; dstRec: IwbMainRecord);
function rcore(src, mst, dst: IwbElement; dstrec: IwbMainRecord;
obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;
implementation
var
firstLink: string;
bLinkProcessed: boolean;
{
ElementByKey:
Gets an element from a container, @e, matching a specified @key.
If @bUseSortKey is true uses SortKey, else uses GetAllValues.
}
function ElementByKey(e: IwbElement; key: string; bUseSortKey: boolean): IwbElement;
var
i: Integer;
c: IwbContainerElementRef;
element: IwbElement;
eKey: string;
begin
if not Supports(e, IwbContainerElementRef, c) then
exit;
// loop through children elements
for i := 0 to Pred(c.ElementCount) do begin
element := c.Elements[i];
// get sort key if bUseSortKey, else get values key
if bUseSortKey then
eKey := element.SortKey[false]
else
eKey := GetAllValues(element);
// if keys match result is current element
if eKey = key then begin
Result := element;
break;
end;
end;
end;
{
HandleElementLife:
Called by rcore. Handles the creation/deletion of elements in the
destination patch record @dstRec.
}
function HandleElementLife(srcCont, dstCont, mstCont: IwbContainerElementRef;
dstRec: IwbMainRecord; obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;
var
i: Integer;
element: IwbElement;
eObj: ISuperObject;
process, bInDestination, bInMaster: boolean;
eLink: String;
begin
Result := false;
// handle element creation
for i := 0 to Pred(srcCont.ElementCount) do begin
element := srcCont.Elements[i];
// if the element isn't in the destination record
// and wasn't in the master record, copy it to the destination
// if it isn't in the destination but is in the master it means
// that it was deleted and shouldn't be copied.
bInDestination := Assigned(dstCont.ElementByName[element.Name]);
bInMaster := Assigned(mstCont.ElementByName[element.Name]);
if (not bInDestination) and (bOverride or not bInMaster) then begin
Result := true;
if bSingle then
exit;
// skip according to setting
eObj := GetElementObj(obj, element.Name);
process := Assigned(eObj) and (eObj.I['p'] = 1);
if not process then begin
if settings.debugSkips then
Tracker.Write(' Skipping element creation at '+element.Path);
continue;
end;
// copy element
try
if settings.debugChanges then
Tracker.Write(' Created element at '+element.Path);
wbCopyElementToRecord(element, dstRec, false, true);
// if another element is linked to the element, copy it
eLink := eObj.S['lf'];
if (eLink <> '') then begin
firstLink := eLink;
bLinkProcessed := false;
CopyLinkedElement(srcCont, dstCont, eLink, obj, dstRec);
end;
except
on x: Exception do
Tracker.Write(' HandleElementLife: Failed to copy '+element.Path+', '+x.Message);
end;
end;
end;
// handle element deletion
if bDeletions then begin
for i := Pred(dstCont.ElementCount) downto 0 do begin
element := dstCont.Elements[i];
if Assigned(mstCont.ElementByName[element.Name]) and
not Assigned(srcCont.ElementByName[element.Name]) then begin
Result := true;
if bSingle then
exit;
// skip according to setting
eObj := GetElementObj(obj, element.Name);
process := Assigned(eObj) and (eObj.I['p'] = 1);
if not process then begin
if settings.debugSkips then
Tracker.Write(' Skipping element deletion at '+element.Path);
continue;
end;
// remove element
if settings.debugChanges then
Tracker.Write(' Deleted element at '+element.Path);
dstCont.RemoveElement(element);
// if another element is linked to the element, copy it
eLink := eObj.S['lf'];
if (eLink <> '') then begin
firstLink := eLink;
bLinkProcessed := false;
CopyLinkedElement(srcCont, dstCont, eLink, obj, dstRec);
end;
end;
end;
end;
end;
// GetMasterElement: Gets the first instance of an element (the master)
function GetMasterElement(src, se: IwbElement; dstRec: IwbMainRecord): IwbElement;
const
debugGetMaster = false;
var
i: integer;
path, key: string;
mstRec, ovr: IwbMainRecord;
mst: IwbElement;
bSorted: boolean;
begin
Result := nil;
mstRec := dstRec.MasterOrSelf;
path := IndexedPath(src);
bSorted := IsSorted(src);
// if sorted, use SortKey, else use GetAllValues
if bSorted then
key := se.SortKey[false]
else
key := GetAllValues(se);
// debug message
if debugGetMaster then
Tracker.Write(' Called GetMasterElement at path '+path+' looking for key '+key);
// loop from override 0 to the second to last override
// last override is in our patch, we don't want to process that one
for i := 0 to mstRec.OverrideCount - 2 do begin
ovr := mstRec.Overrides[i];
mst := ElementByIndexedPath(mstRec, path);
Result := ElementByKey(mst, key, bSorted);
// break if we found a subrecord matching the sortkey
if Result <> nil then
break;
end;
end;
{
BuildKeyList:
Creates a list of element keys for elements in @container in a stringlist @sl.
Uses SortKey if @bUseSortKeys is true, else uses GetAllValues.
}
procedure BuildKeyList(container: IwbContainerElementRef; var sl: TStringList;
bUseSortKeys: boolean);
var
i, n: integer;
childElement: IwbElement;
key, adjustedKey: string;
begin
// loop through children elements
for i := 0 to Pred(container.ElementCount) do begin
childElement := container.Elements[i];
// use sort if bUseSortKeys is true, else use GetAllValues
if bUseSortKeys then
key := childElement.SortKey[false]
else
key := GetAllValues(childElement);
// find a non-colliding key
n := 0;
adjustedKey := key;
while (sl.IndexOf(adjustedKey) > -1) do begin
Inc(n);
adjustedKey := key + IntToStr(n);
end;
// add adjusted key to stringlist
sl.Add(adjustedKey);
end;
end;
{
MergeArray:
Merges a sorted or unsorted arrray element by comparing element
keys. Compares a source array @src, against a master array @mst and
a destination array @dst. Returns true if any changes are made.
Exits before making any changes if @bSingle is true. Preserves
deletions if @bDeletions if true. Tracks @dstRec and @obj for
calling rcore on element containers in sorted arrays.
}
function MergeArray(src, mst, dst: IwbElement; dstrec: IwbMainRecord;
obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;
var
i, s_ndx, m_ndx, d_ndx: integer;
se, de: IwbElement;
slMst, slDst, slSrc: TStringList;
srcCont, dstCont, mstCont, seCont: IwbContainerElementRef;
bSorted: boolean;
begin
Result := false;
// exit if input array elements can't be treated as a containers
if not Supports(src, IwbContainerElementRef, srcCont) then
exit;
if not Supports(mst, IwbContainerElementRef, mstCont) then
exit;
if not Supports(dst, IwbContainerElementRef, dstCont) then
exit;
// determine if we're handling a sorted array
bSorted := IsSorted(src);
// Build lists of element keys in each array for easy comparison
slSrc := TStringList.Create;
slMst := TStringList.Create;
slDst := TStringList.Create;
try
BuildKeyList(srcCont, slSrc, bSorted);
BuildKeyList(mstCont, slMst, bSorted);
BuildKeyList(dstCont, slDst, bSorted);
// ELEMENT DELETION:
// Remove elements that are in master and destination, but
// missing from source
if bDeletions then
for i := 0 to Pred(slMst.Count) do begin
s_ndx := slSrc.IndexOf(slMst[i]);
// element from master isn't in source
if (s_ndx = -1) then begin
Result := true;
// if we're in a treat as single, exit without removing anything
if bSingle then exit;
// if element is present in destination, remove it
d_ndx := slDst.IndexOf(slMst[i]);
if (d_ndx = -1) then continue;
if settings.debugArrays then
Tracker.Write(' > Removing element at '+dst.Path+' with key: '+slMst[i]);
dstCont.RemoveElement(d_ndx);
slDst.Delete(d_ndx);
end;
end;
// ELEMENT ADDITION:
// Copy array elements in source that aren't in master
// or destination
for i := 0 to Pred(slSrc.Count) do begin
d_ndx := slDst.IndexOf(slSrc[i]);
m_ndx := slMst.IndexOf(slSrc[i]);
se := srcCont.Elements[i];
if (d_ndx = -1) and ((m_ndx = -1) or bOverride) then begin
Result := true;
// if we're in a treat as single, exit without adding anything
if bSingle then exit;
// add element to destination
if settings.debugArrays then
Tracker.Write(' > Adding element at '+dst.Path+' with key: '+slSrc[i]);
de := dstCont.Assign(dstCont.ElementCount, se, false);
if bSorted then
slDst.Insert(dstCont.IndexOf(de), slSrc[i])
else
slDst.Add(slSrc[i]);
end
// Special handling for sorted arrays
// Traverses elements that may have been modified without their sortkey changing
else if bSorted and (d_ndx > -1) and Supports(se, IwbContainerElementRef, seCont)
and (seCont.ElementCount > 0) then begin
if settings.debugArrays then begin
Tracker.Write(' > Traversing element '+se.Path+' with key: '+slSrc[i]);
Tracker.Write(' > Source Element: '+GetAllValues(se));
Tracker.Write(' > Destination Element: '+GetAllValues(dstCont.Elements[d_ndx]));
end;
// traverse element
try
Result := rcore(se, GetMasterElement(src, se, dstrec), dstCont.Elements[d_ndx],
dstrec, GetElementObj(obj, se.Name), bSingle, bDeletions, bOverride);
if Result and bSingle then
exit;
except on x : Exception do begin
Tracker.Write(' rcore: Exception at '+se.Path+': '+x.Message);
end;
end;
end;
end;
finally
// free lists
slMst.Free;
slSrc.Free;
slDst.Free;
end;
end;
{
CopyElementValue:
Copies the edit value of @se to @de.
}
procedure CopyElementValue(se, me, de: IwbElement);
begin
if not de.IsEditable then begin
if settings.debugChanges then begin
Tracker.Write(' Unable to copy element value on '+se.path);
Tracker.Write(' Element is not editable');
end;
exit;
end;
if Assigned(me) and settings.debugChanges then begin
if (not settings.debugTraversal) then
Tracker.Write(' '+se.Path);
Tracker.Write(' > Found differing values: '+se.EditValue+', '+me.EditValue);
end;
// try to copy element value to destination element from source element
try
de.EditValue := se.EditValue;
except on x : Exception do
Tracker.Write(' CopyElementValue: Exception '+x.Message);
end;
end;
{
CopyLinkedElement:
Copies the linked element named eLink, and then copies any elements it is
linked to.
}
procedure CopyLinkedElement(srcCont, dstCont: IwbContainerElementRef;
eLink: string; obj: ISuperObject; dstRec: IwbMainRecord);
var
cObj: ISuperObject;
le, de: IwbElement;
cLink: string;
begin
// exit if we reached the first link in a chain
if (eLink = firstLink) then begin
if bLinkProcessed then
exit;
bLinkProcessed := true;
end;
// else try to copy the linked element
try
cObj := GetElementObj(obj, eLink);
le := srcCont.ElementByName[eLink];
de := dstCont.ElementByName[eLink];
if Assigned(le) then begin
if settings.debugLinks then
Tracker.Write(' Copying linked element '+le.Path);
if Assigned(de) then
de.Assign(Low(Integer), le, false)
else
dstCont.AddIfMissing(le, true, true, '', '', '');
// follow chain
cLink := cObj.S['lf'];
if cLink <> '' then
CopyLinkedElement(srcCont, dstCont, cLink, obj, dstRec);
end;
except
on x: Exception do
Tracker.Write(' CopyLinkedElement: Failed to copy '+eLink+', '+x.Message);
end;
end;
{
HandleElement:
Wrapper function around the logic for recursing into child
elements (rcore), handling an array, or copying element values.
}
function HandleElement(se, me, de: IwbElement; dstRec: IwbMainRecord;
obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;
var
srcType, dstType: TSmashType;
container: IwbContainerElementRef;
bCanAdd, bIsContainer: boolean;
seVal, meVal: string;
begin
Result := false;
// deftype and elementtype
srcType := GetSmashType(se);
dstType := GetSmashType(de);
// other type information
bIsContainer := Supports(se, IwbContainerElementRef, container)
and (container.ElementCount > 0);
bCanAdd := se.CanAssign(High(Integer), nil, True)
and not (esNotSuitableToAddTo in se.ElementStates);
// exit if srcType <> dstType, returning true
if srcType <> dstType then begin
if settings.debugSkips then begin
Tracker.Write(' Source and destination types don''t match');
Tracker.Write(' '+stToString(srcType)+' != '+stToString(dstType));
Tracker.Write(' Skipping '+se.Path);
end;
Result := True;
exit;
end;
// exit if master element not assigned and not array
if not Assigned(me) then begin
if bCanAdd and (srcType in stArrays) then
me := de
else begin
if settings.debugSkips then begin
Tracker.Write(' Master element not found!');
Tracker.Write(' Skipping '+se.Path);
end;
exit;
end;
end;
// debug messages
if settings.debugTraversal then
Tracker.Write(' '+se.Path);
if settings.debugTypes then begin
Tracker.Write(' bCanAdd: '+BoolToStr(bCanAdd, true));
Tracker.Write(' SmashType: '+stToString(srcType));
end;
// merge array
if bCanAdd and (srcType in stArrays) then begin
if settings.debugTraversal then
Tracker.Write(' Merging array');
try
Result := MergeArray(se, me, de, dstrec, obj, bSingle, bDeletions, bOverride);
except on x : Exception do
Tracker.Write(' MergeArray: Exception at '+se.Path+': '+x.Message);
end;
end
// else recurse deeper
else if bIsContainer and (srcType <> stInteger) then begin
if settings.debugTraversal then
Tracker.Write(' Recursing deeper');
try
Result := rcore(se, me, de, dstrec, obj, bSingle, bDeletions, bOverride);
except on x : Exception do
Tracker.Write(' rcore: Exception at '+se.Path+': '+x.Message);
end;
end
// else copy element value
else if (srcType in stValues) then begin
seVal := se.EditValue;
meVal := me.EditValue;
if (seVal <> meVal) then begin
if not bSingle then
CopyElementValue(se, me, de);
Result := true;
end
else if settings.debugSkips then begin
Tracker.Write(Format(' Skipping, "%s" = "%s"', [seVal, meVal]));
end;
end
else if settings.debugSkips then begin
Tracker.Write(Format(' Skipping, %s is not a value type',
[stToString(srcType)]));
end;
end;
{
rcore:
Recursively copy overridden elements. Recursively traverses elements,
comparing between a source element (from an override record) @src, a
master element @mst, and a destination element @dst. Tracks the
destination patch record for element copying through @dstRec. Uses a
json tree @obj to determine user settings for traversal. Uses @bSingle
to determine when we're in a "single entity" as specified by the user,
and @bDeletions to determine when it's ok to delete removed elements
from the destination patch record.
- Uses HandleElementLife to resolve element creation/deletion.
- Uses HandleElement to handle arrays, recurse deeper, or copy element
values
}
function rcore(src, mst, dst: IwbElement; dstRec: IwbMainRecord;
obj: ISuperObject; bSingle, bDeletions, bOverride: boolean): boolean;
var
i: integer;
srcCont, dstCont, mstCont: IwbContainerElementRef;
se, me, de: IwbElement;
process, eSingle, eDeletions, eOverride: boolean;
eObj: ISuperObject;
eLink: string;
begin
Result := false;
// prepare containers
if not Supports(src, IwbContainerElementRef, srcCont) then begin
if settings.debugSkips then begin
Tracker.Write(' Source element not a container.');
Tracker.Write(' Skipping '+src.Path);
end;
exit;
end;
if not Supports(dst, IwbContainerElementRef, dstCont) then begin
if settings.debugSkips then begin
Tracker.Write(' Destination element not a container.');
Tracker.Write(' Skipping '+src.Path);
end;
exit;
end;
if not Supports(mst, IwbContainerElementRef, mstCont) then begin
if settings.debugSkips then begin
Tracker.Write(' Master element not a container.');
Tracker.Write(' Skipping '+src.Path);
end;
exit;
end;
// copy elements from source to destination if missing AND
// delete elements missing from source if found in master and destination
Result := HandleElementLife(srcCont, dstCont, mstCont, dstRec, obj, bSingle, bDeletions, bOverride);
if bSingle and Result then begin
if settings.debugSingle then
Tracker.Write(' Single entity change found at '+src.Path);
exit;
end;
// loop through subelements
for i := 0 to Pred(srcCont.ElementCount) do begin
// assign source, destination, master elements
se := srcCont.Elements[i];
de := dstCont.ElementByName[se.Name];
me := mstCont.ElementByName[se.Name];
// skip if destination element not assigned
if not Assigned(de) then begin
if settings.debugSkips then begin
Tracker.Write(' Destination element not found!');
Tracker.Write(' Skipping '+se.Path);
end;
continue;
end;
// skip according to setting
eObj := GetElementObj(obj, se.Name);
process := Assigned(eObj) and (eObj.I['p'] = 1);
if not process then begin
if settings.debugSkips then
Tracker.Write(' Skipping '+se.Path);
continue;
end;
// set element treat as single entity / ignore deletions booleans
eSingle := bSingle or (eObj.I['s'] = 1);
eDeletions := bDeletions or (eObj.I['d'] = 1);
eOverride := bOverride or (eObj.I['o'] = 1);
// handle element
Result := HandleElement(se, me, de, dstRec, eObj, eSingle, eDeletions, eOverride);
// if we're in a single entity and an element is changed, break
// we don't need to handle anything anymore
if bSingle and Result then begin
if settings.debugSingle then
Tracker.Write(' Single entity change found at '+se.Path);
break;
end;
// if the element we're processing has the single entity flag set
// and we're not currently in a single entity, copy entire element
if eSingle and (not bSingle) and Result then try
if settings.debugSingle then
Tracker.Write(Format(' Copying single entity %s', [se.path]));
de.Assign(Low(Integer), se, false);
except
on x: Exception do
Tracker.Write(' rcore: Failed to copy '+se.Path+', '+x.Message);
end;
// if another element is linked to the element being processed
// and the element being processed has been modified, copy the linked
// element
eLink := eObj.S['lf'];
if Result and (eLink <> '') then begin
firstLink := eLink;
bLinkProcessed := false;
CopyLinkedElement(srcCont, dstCont, eLink, obj, dstRec);
end;
end;
end;
end.
================================================
FILE: frontend/msChoicePanel.pas
================================================
unit msChoicePanel;
interface
uses
SysUtils, Classes, Controls, Dialogs, Graphics, Buttons, StdCtrls, ExtCtrls,
ImgList, Types,
// mte components
mteHelpers,
// mp components
msCore;
type
TSenderCallback = procedure(Sender: TObject) of object;
TChoicePanel = class(TPanel)
public
Selected: boolean;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure ToggleSelect(Sender: TObject);
procedure SettingChanged(Sender: TObject);
procedure Deselect;
procedure Select;
procedure SetTop(top: Integer);
procedure SetWidth(width: Integer);
function GetSetting: TSmashSetting;
function GetLabel: string;
procedure SetSelectCallback(callback: TNotifyEvent);
procedure SetLabel(sig: string);
procedure AddChoice(choice: TSmashSetting);
private
lstChoices: TList;
ColorUnselected: Integer;
ColorSelected: Integer;
lblSig: TLabel;
cbChoices: TComboBox;
SelectCallback: TNotifyEvent;
end;
implementation
{******************************************************************************}
{ TChoicePanel
A GUI component for interacting with a profile.
}
{******************************************************************************}
constructor TChoicePanel.Create(AOwner: TComponent);
begin
// set up panel
inherited Create(AOwner);
Parent := AOwner as TWinControl;
Width := (AOwner as TWinControl).ClientWidth;
Height := 36;
Left := 0;
Top := 0;
ParentBackground := false;
ParentColor := false;
ParentDoubleBuffered := false;
Cursor := crHandPoint;
Anchors := [akLeft, akTop, akRight];
Visible := true;
// set local variables
Selected := false;
ColorUnselected := Color;
ColorSelected := $f0ece4;
lstChoices := TList.Create;
// create components
lblSig := TLabel.Create(self);
cbChoices := TComboBox.Create(self);
// set up lblSig
lblSig.Parent := self;
lblSig.Top := 10;
lblSig.Left := 16;
lblSig.Caption := 'SIGN';
lblSig.Cursor := crHandPoint;
lblSig.Align := alCustom;
lblSig.Anchors := [akLeft, akTop];
// set up cbGame
cbChoices.Parent := self;
cbChoices.Top := 8;
cbChoices.Left := 75;
cbChoices.Width := Width - cbChoices.Left - 6;
cbChoices.Style := csDropDownList;
cbChoices.Items.Text := '';
cbChoices.Items.Add('Patch');
cbChoices.ItemIndex := 0;
cbChoices.Align := alCustom;
cbChoices.Anchors := [akLeft, akTop, akRight];
// set event handlers
self.OnClick := ToggleSelect;
lblSig.OnClick := ToggleSelect;
cbChoices.OnChange := SettingChanged;
end;
destructor TChoicePanel.Destroy;
begin
lblSig.Free;
cbChoices.Free;
lstChoices.Free;
inherited;
end;
{ EVENT HANDLING }
procedure TChoicePanel.SettingChanged(Sender: TObject);
begin
if Assigned(SelectCallback) then SelectCallback(self);
end;
procedure TChoicePanel.ToggleSelect(Sender: TObject);
begin
if Cursor = crHandPoint then begin
if Selected then Deselect else Select;
if Assigned(SelectCallback) then SelectCallback(self);
end;
end;
procedure TChoicePanel.Select;
begin
Selected := true;
Color := ColorSelected;
Repaint;
end;
procedure TChoicePanel.Deselect;
begin
Selected := false;
Color := ColorUnselected;
Repaint;
end;
procedure TChoicePanel.SetTop(top: Integer);
begin
self.top := top;
end;
procedure TChoicePanel.SetWidth(width: Integer);
begin
self.width := width;
end;
function TChoicePanel.GetSetting: TSmashSetting;
begin
Result := nil;
if cbChoices.ItemIndex = 0 then
exit;
Result := TSmashSetting(lstChoices[cbChoices.ItemIndex - 1]);
end;
function TChoicePanel.GetLabel: string;
begin
Result := lblSig.Caption;
end;
procedure TChoicePanel.SetSelectCallback(callback: TNotifyEvent);
begin
SelectCallback := callback;
end;
procedure TChoicePanel.SetLabel(sig: string);
begin
lblSig.Caption := sig;
end;
procedure TChoicePanel.AddChoice(choice: TSmashSetting);
begin
lstChoices.Add(choice);
cbChoices.Items.Add(choice.name);
cbChoices.ItemIndex := 0;
end;
end.
================================================
FILE: frontend/msConfiguration.pas
================================================
unit msConfiguration;
interface
uses
Classes, wbInterface,
// mte units
mteHelpers, RttiIni;
type
TGameMode = Record
longName: string;
gameName: string;
gameMode: TwbGameMode;
regName: string;
appName: string;
exeName: string;
appIDs: string;
bsaOptMode: string;
end;
TSettings = class(TObject)
public
[IniSection('General')]
profile: string;
newProfile: boolean;
gameMode: integer;
gamePath: string;
language: string;
simpleDictionaryView: boolean;
simplePluginsView: boolean;
simpleSplash: boolean;
[IniSection('Advanced')]
generalMessageColor: Int64;
clientMessageColor: Int64;
loadMessageColor: Int64;
patchMessageColor: Int64;
pluginMessageColor: Int64;
errorMessageColor: Int64;
logMessageTemplate: string;
preserveTempPath: boolean;
allowTagging: boolean;
smashSound: boolean;
[IniSection('Patching')]
patchDirectory: string;
debugPatchStatus: boolean;
debugMasters: boolean;
debugArrays: boolean;
debugSkips: boolean;
debugTraversal: boolean;
debugTypes: boolean;
debugChanges: boolean;
debugSingle: boolean;
debugLinks: boolean;
buildRefs: boolean;
preserveITPOs: boolean;
constructor Create; virtual;
end;
TStatistics = class(TObject)
public
[IniSection('Statistics')]
timesRun: integer;
patchesBuilt: integer;
pluginsPatched: integer;
settingsSubmitted: integer;
recsSubmitted: integer;
constructor Create; virtual;
end;
TProfile = class(TObject)
public
name: string;
gameMode: Integer;
gamePath: string;
constructor Create(name: string); virtual;
procedure Clone(p: TProfile);
procedure Delete;
procedure Rename(name: string);
end;
TProgramStatus = class(TObject)
public
bInitException, bLoadException, bChangeProfile, bForceTerminate,
bLoaderDone, bInstallUpdate, bUpdatePatchStatus, bClose: boolean;
GameMode: TGameMode;
Version: String;
constructor Create; virtual;
end;
procedure DeleteTempPath;
procedure LoadLanguage;
function GetLanguageString(name: string): string;
procedure SaveProfile(var p: TProfile);
procedure LoadSettings; overload;
function LoadSettings(path: string): TSettings; overload;
procedure SaveSettings; overload;
procedure SaveSettings(var s: TSettings; path: string); overload;
procedure LoadStatistics;
procedure SaveStatistics;
var
settings: TSettings;
CurrentProfile: TProfile;
statistics, sessionStatistics: TStatistics;
language, PathList: TStringList;
ProgramStatus: TProgramStatus;
const
// IMPORTANT CONSTANTS
bTranslationDump = false;
// GAME MODES
GameArray: array[1..6] of TGameMode = (
( longName: 'Skyrim'; gameName: 'Skyrim'; gameMode: gmTES5;
regName: 'Skyrim'; appName: 'TES5'; exeName: 'TESV.exe'; appIDs: '72850';
bsaOptMode: 'sk'; ),
( longName: 'Oblivion'; gameName: 'Oblivion'; gameMode: gmTES4;
regName: 'Oblivion'; appName: 'TES4'; exeName: 'Oblivion.exe';
appIDs: '22330,900883'; bsaOptMode: 'ob'; ),
( longName: 'Fallout New Vegas'; gameName: 'FalloutNV'; gameMode: gmFNV;
regName: 'FalloutNV'; appName: 'FNV'; exeName: 'FalloutNV.exe';
appIDs: '22380,2028016'; bsaOptMode: 'fo'; ),
( longName: 'Fallout 3'; gameName: 'Fallout3'; gameMode: gmFO3;
regName: 'Fallout3'; appName: 'FO3'; exeName: 'Fallout3.exe';
appIDs: '22300,22370'; bsaOptMode: 'fo'; ),
( longName: 'Fallout 4'; gameName: 'Fallout4'; gameMode: gmFO4;
regName: 'Fallout4'; appName: 'FO4'; exeName: 'Fallout4.exe';
appIDs: '377160'; bsaOptMode: ''; ),
( longName: 'Skyrim Special Edition'; gameName: 'Skyrim'; gameMode: gmSSE;
regName: 'Skyrim Special Edition'; appName: 'SSE';
exeName: 'SkyrimSE.exe'; appIDs: '489830'; bsaOptMode: ''; )
);
implementation
uses
Graphics, SysUtils, Dialogs, ShellAPI, Windows, Registry;
{ TSettings }
constructor TSettings.Create;
begin
// default settings
newProfile := true;
language := 'English';
simpleDictionaryView := false;
simplePluginsView := false;
patchDirectory := wbDataPath;
generalMessageColor := clGreen;
loadMessageColor := clPurple;
clientMessageColor := clBlue;
patchMessageColor := $000080FF;
pluginMessageColor := $00484848;
errorMessageColor := clRed;
logMessageTemplate := '[{{AppTime}}] ({{Group}}) {{Label}}: {{Text}}';
end;
{ TStatistics constructor }
constructor TStatistics.Create;
begin
timesRun := 0;
patchesBuilt := 0;
pluginsPatched := 0;
settingsSubmitted := 0;
recsSubmitted := 0;
end;
{ TProfile }
constructor TProfile.Create(name: string);
begin
self.name := name;
end;
procedure TProfile.Clone(p: TProfile);
begin
name := p.name;
gameMode := p.gameMode;
gamePath := p.gamePath;
end;
procedure TProfile.Delete;
var
path: string;
begin
path := PathList.Values['ProgramPath'] + 'profiles\' + name;
if DirectoryExists(path) then
DeleteToRecycleBin(path, false);
end;
procedure TProfile.Rename(name: string);
var
oldProfilePath, newProfilePath: string;
begin
// rename old profile folder if necessary
oldProfilePath := PathList.Values['ProgramPath'] + 'profiles\' + self.name;
newProfilePath := PathList.Values['ProgramPath'] + 'profiles\' + name;
if DirectoryExists(oldProfilePath) then
RenameFile(oldProfilePath, newProfilePath);
// then change name in the object
self.name := name;
end;
{ TProgramStatus }
constructor TProgramStatus.Create;
begin
bInitException := false;
bLoadException := false;
bChangeProfile := false;
bForceTerminate := false;
bUpdatePatchStatus := false;
bClose := false;
Version := GetVersionMem;
end;
{ CONFIGURATION HELPERS }
procedure DeleteTempPath;
begin
DeleteDirectory(PathList.Values['TempPath']);
end;
procedure LoadLanguage;
const
langFile = 'http://raw.githubusercontent.com/matortheeternal/smash/master/frontend/lang/english.lang';
directions = 'Your english.lang file is missing. Please download it from GitHub. ' +
'After you click OK, a webpage with the file will be opened. Right-click the ' +
'page and choose "Save page as", then save it as english.lang in the "lang\" ' +
'folder where you have MatorSmash.exe installed.';
accessMessage = 'It looks like Smash doesn''t have permission to read files ' +
'from disk. Try running the program as administrator or disabling your antivirus.';
var
filename: string;
begin
filename := Format('lang\%s.lang', [settings.language]);
language := TStringList.Create;
if (not FileExists(filename)) then begin
if settings.language <> 'english' then begin
settings.language := 'english';
LoadLanguage;
end
else if not FileExists('MatorSmash.exe') then
MessageDlg(accessMessage, mtConfirmation, [mbOk], 0)
else begin
MessageDlg(directions, mtConfirmation, [mbOk], 0);
ForceDirectories(PathList.Values['ProgramPath'] + 'lang\');
ShellExecute(0, 'open', PChar(langFile), '', '', SW_SHOWNORMAL);
end;
end
else
language.LoadFromFile(filename);
end;
function GetLanguageString(name: string): string;
begin
if language.Values[name] <> '' then
Result := StringReplace(language.Values[name], '#13#10', #13#10, [rfReplaceAll])
else
Result := name;
end;
procedure SaveProfile(var p: TProfile);
var
path: string;
pSettings: TSettings;
begin
// get profile path
path := PathList.Values['ProgramPath'] + 'profiles\' + p.name + '\settings.ini';
ForceDirectories(ExtractFilePath(path));
// load settings if they exist, else create them
if FileExists(path) then
pSettings := LoadSettings(path)
else begin
pSettings := TSettings.Create;
pSettings.patchDirectory := p.gamePath + 'Data\';
end;
// save profile details to settings
pSettings.profile := p.name;
pSettings.gameMode := p.gameMode;
pSettings.gamePath := p.gamePath;
SaveSettings(pSettings, path);
end;
procedure SaveSettings;
begin
// user saving settings from options form
settings.newProfile := false;
TRttiIni.Save(PathList.Values['ProfilePath'] + 'settings.ini', settings);
end;
procedure SaveSettings(var s: TSettings; path: string);
begin
TRttiIni.Save(path, s);
end;
procedure LoadSettings;
begin
settings := TSettings.Create;
TRttiIni.Load(PathList.Values['ProfilePath'] + 'settings.ini', settings);
end;
function LoadSettings(path: string): TSettings;
begin
Result := TSettings.Create;
TRttiIni.Load(path, Result);
end;
procedure SaveStatistics;
begin
// move session statistics to general statistics
Inc(statistics.timesRun, sessionStatistics.timesRun);
Inc(statistics.patchesBuilt, sessionStatistics.patchesBuilt);
Inc(statistics.pluginsPatched, sessionStatistics.pluginsPatched);
Inc(statistics.settingsSubmitted, sessionStatistics.settingsSubmitted);
Inc(statistics.recsSubmitted, sessionStatistics.recsSubmitted);
// zero out session statistics
sessionStatistics.timesRun := 0;
sessionStatistics.patchesBuilt := 0;
sessionStatistics.settingsSubmitted := 0;
sessionStatistics.recsSubmitted := 0;
// save to file
TRttiIni.Save('statistics.ini', statistics);
end;
procedure LoadStatistics;
begin
statistics := TStatistics.Create;
sessionStatistics := TStatistics.Create;
TRttiIni.Load('statistics.ini', statistics);
end;
initialization
begin
ProgramStatus := TProgramStatus.Create;
PathList := TStringList.Create;
end;
finalization
begin
ProgramStatus.Free;
PathList.Free;
end;
end.
================================================
FILE: frontend/msConflict.pas
================================================
unit msConflict;
interface
uses
Classes, SysUtils,
// mte units
mteBase,
// ms units
msCore,
// xEdit units
wbInterface, wbImplementation, wbHelpers;
type
// States used in InitNode to indicate states a node shall initially have.
TVirtualNodeInitState = (
ivsDisabled,
ivsExpanded,
ivsHasChildren,
ivsMultiline,
ivsSelected,
ivsFiltered,
ivsReInit{>>>},
ivsHidden{<<<}
);
TVirtualNodeInitStates = set of TVirtualNodeInitState;
// navnode flags
TNavNodeFlag = (
nnfInjected,
nnfNotReachable,
nnfReferencesInjected
);
TNavNodeFlags = set of TNavNodeFlag;
// navnode data
PNavNodeData = ^TNavNodeData;
TNavNodeData = record
Element : IwbElement;
Container : IwbContainer;
ConflictAll : TConflictAll;
ConflictThis : TConflictThis;
Flags : TNavNodeFlags;
end;
// node flags
TViewNodeFlag = (
vnfDontShow,
vnfIgnore
);
TViewNodeFlags = set of TViewNodeFlag;
// node data
PViewNodeData = ^TViewNodeData;
TViewNodeData = record
Element: IwbElement;
Container: IwbContainerElementRef;
ConflictAll: TConflictAll;
ConflictThis: TConflictThis;
ViewNodeFlags: TViewNodeFlags;
end;
// collections of node datas
TViewNodeDatas = array[Word] of TViewNodeData;
PViewNodeDatas = ^TViewNodeDatas;
TDynViewNodeDatas = array of TViewNodeData;
// exposed methods
procedure ConflictLevelForMainRecord(const aMainRecord: IwbMainRecord;
out aConflictAll: TConflictAll; out aConflictThis: TConflictThis);
function ConflictLevelForChildNodeDatas(const aNodeDatas: TDynViewNodeDatas;
aSiblingCompare, aInjected: Boolean): TConflictAll;
function ConflictLevelForNodeDatas(const aNodeDatas: PViewNodeDatas;
aNodeCount: Integer; aSiblingCompare, aInjected: Boolean): TConflictAll;
function ConflictAllForElements(e1, e2: IwbElement; aSiblingCompare,
aInjected: Boolean): TConflictAll;
function ConflictThisForMainRecord(aMainRecord: IwbMainRecord): TConflictThis;
function ConflictAllForMainRecord(aMainRecord: IwbMainRecord): TConflictAll;
function IsITPO(rec: IwbMainRecord): Boolean;
function IsITM(rec: IwbMainRecord): Boolean;
implementation
procedure AppendToNodeDatas(var NodeDatas: TDynViewNodeDatas; e: IwbElement);
var
Container: IwbContainerElementRef;
begin
SetLength(NodeDatas, Succ(Length(NodeDatas)));
NodeDatas[Pred(Length(NodeDatas))].Element := e;
if Supports(e, IwbContainerElementRef, Container) and (Container.ElementCount > 0) then
NodeDatas[Pred(Length(NodeDatas))].Container := Container;
end;
function ConflictAllForElements(e1, e2: IwbElement; aSiblingCompare,
aInjected: Boolean): TConflictAll;
var
NodeDatas: TDynViewNodeDatas;
begin
// prepare node datas
AppendToNodeDatas(NodeDatas, e1);
AppendToNodeDatas(NodeDatas, e2);
// compute the conflict level
Result := caUnknown;
if Length(NodeDatas) > 0 then
if Assigned(NodeDatas[0].Container) then
Result := ConflictLevelForChildNodeDatas(NodeDatas, aSiblingCompare, aInjected)
else
Result := ConflictLevelForNodeDatas(@NodeDatas[0], Length(NodeDatas), aSiblingCompare, aInjected);
end;
function NodeDatasForMainRecord(const aMainRecord: IwbMainRecord): TDynViewNodeDatas;
var
Master : IwbMainRecord;
Rec : IwbMainRecord;
i, j : Integer;
Records : TStringList;
AnyHidden : Boolean;
IsNonOverride : Boolean;
EditorID : string;
FormID : Cardinal;
LoadOrder : Integer;
Group : IwbGroupRecord;
Signature : TwbSignature;
plugin : TPlugin;
aFile : IwbFile;
begin
Assert(wbLoaderDone);
IsNonOverride := False;
AnyHidden := False;
if aMainRecord.Signature = 'GMST' then begin
IsNonOverride := True;
EditorID := aMainRecord.EditorID;
SetLength(Result, PluginsList.Count);
Master := nil;
for i := 0 to Pred(PluginsList.Count) do begin
plugin := TPlugin(PluginsList[i]);
aFile := plugin._File;
Group := aFile.GroupBySignature['GMST'];
if Assigned(Group) then begin
Rec := Group.MainRecordByEditorID[EditorID];
if Assigned(Rec) then begin
if not Assigned(Master) then
Master := Rec;
Result[i].Element := Rec;
end;
end;
end;
end else if (aMainRecord.Signature = 'NAVI') (* or (aMainRecord.Signature = 'TES4') *) then begin
IsNonOverride := True;
Signature := aMainRecord.Signature;
FormID := aMainRecord.FormID;
LoadOrder := aMainRecord.GetFile.LoadOrder;
SetLength(Result, 0);
Master := nil;
for i := 0 to Pred(PluginsList.Count) do begin
plugin := TPlugin(PluginsList[i]);
aFile := plugin._File;
if aFile.LoadOrder = LoadOrder then begin
Group := aFile.GroupBySignature[Signature];
if Assigned(Group) then begin
Rec := Group.MainRecordByFormID[FormID];
if Assigned(Rec) then begin
j := Length(Result);
SetLength(Result, j+1);
if not Assigned(Master) then
Master := Rec;
Result[j].Element := Rec;
end;
end;
end;
end;
end else if (aMainRecord.Signature = 'TES4') then begin
IsNonOverride := True;
Signature := aMainRecord.Signature;
LoadOrder := aMainRecord.GetFile.LoadOrder;
SetLength(Result, 0);
Master := nil;
for i := 0 to Pred(PluginsList.Count) do begin
plugin := TPlugin(PluginsList[i]);
aFile := plugin._File;
if aFile.LoadOrder = LoadOrder then begin
// header of .dat file, show only itself
if SameText(ExtractFileExt(aMainRecord.GetFile.FileName), '.dat') and not SameText(ExtractFileExt(aFile.FileName), '.dat') then
Continue;
// skip .dat file header by default
if not SameText(ExtractFileExt(aMainRecord.GetFile.FileName), '.dat') and SameText(ExtractFileExt(aFile.FileName), '.dat') then
Continue;
Rec := aFile.Elements[0] as IwbMainRecord;
if Assigned(Rec) then begin
j := Length(Result);
SetLength(Result, j+1);
if not Assigned(Master) then
Master := Rec;
Result[j].Element := Rec;
end;
end;
end;
end else begin
Master := aMainRecord.MasterOrSelf;
SetLength(Result, Succ(Master.OverrideCount));
AnyHidden := Master.IsHidden;
if not AnyHidden then
for i := 0 to Pred(Master.OverrideCount) do begin
AnyHidden := Master.Overrides[i].IsHidden;
if AnyHidden then
Break;
end;
end;
if (Length(Result) > 1) and ({ModGroupsEnabled or }AnyHidden) or IsNonOverride then begin
Records := TStringList.Create;
try
if IsNonOverride then begin
for i := Low(Result) to High(Result) do
if Supports(Result[i].Element, IwbMainRecord, Rec) then
Records.AddObject(Rec._File.FileName, Pointer(Rec));
Result := nil;
end else begin
Records.AddObject(Master._File.FileName, Pointer(Master));
for i := 0 to Pred(Master.OverrideCount) do begin
Rec := Master.Overrides[i];
Records.AddObject(Rec._File.FileName, Pointer(Rec));
end;
end;
{f ModGroupsEnabled then repeat
MadeChanges := False;
sl := TStringList.Create;
try
for i := 0 to Pred(ModGroups.Count) do begin
sl.Assign(TStrings(ModGroups.Objects[i]));
for j := Pred(sl.Count) downto 0 do begin
k := Records.IndexOf(sl[j]);
if K > 0 then // >, not >=, never hide the original master
sl.Objects[j] := TObject(k)
else
sl.Delete(j);
end;
if sl.Count > 1 then begin
k := Integer(sl.Objects[0]);
j := 1;
if k = 0 then begin
while (j < sl.Count) and (Integer(sl.Objects[j]) = k + 1) do begin
Records.Objects[Integer(sl.Objects[Pred(j)])] := nil;
Inc(k);
Inc(j);
end;
Inc(j);
end;
while (j < sl.Count) do begin
Records.Objects[Integer(sl.Objects[Pred(j)])] := nil;
Inc(j);
end;
for j := Pred(Records.Count) downto 0 do
if Records.Objects[j] = nil then begin
Records.Delete(j);
MadeChanges := True;
end;
end;
if Records.Count < 2 then
Break;
end;
finally
sl.Free;
end;
until not MadeChanges;}
i := 0;
while (i < Records.Count) and (Records.Count > 1) do
if IwbElement(Pointer(Records.Objects[i])).IsHidden then
Records.Delete(i)
else
Inc(i);
SetLength(Result, Records.Count);
for i := 0 to Pred(Records.Count) do
with Result[i] do begin
Rec := IwbMainRecord(Pointer(Records.Objects[i]));
if i = 0 then
Master := Rec;
Container := Rec as IwbContainerElementRef;
Element := Container;
if (Container.ElementCount = 0) or (Rec.Signature <> Master.Signature) then
Container := nil;
end;
finally
FreeAndNil(Records);
end;
Exit;
end;
Result[0].Element := Master;
Result[0].Container := Master as IwbContainerElementRef;
if Master.ElementCount < 1 then
Result[0].Container := nil;
for i := 0 to Pred(Master.OverrideCount) do
with Result[Succ(i)] do begin
Container := Master.Overrides[i] as IwbContainerElementRef;
Element := Container;
if (Container.ElementCount = 0) or (Master.Overrides[i].Signature <> Master.Signature) then
Container := nil;
end;
end;
procedure ConflictLevelForMainRecord(const aMainRecord: IwbMainRecord;
out aConflictAll: TConflictAll; out aConflictThis: TConflictThis);
procedure Fix(const aMainRecord: IwbMainRecord);
begin
with aMainRecord do begin
ConflictAll := aConflictAll;
if ConflictThis = ctUnknown then begin
ConflictThis := ctHiddenByModGroup;
end;
end;
end;
var
NodeDatas : TDynViewNodeDatas;
i : Integer;
Master : IwbMainRecord;
KeepAliveRoot : IwbKeepAliveRoot;
begin
KeepAliveRoot := wbCreateKeepAliveRoot;
aConflictAll := aMainRecord.ConflictAll;
aConflictThis := aMainRecord.ConflictThis;
if aConflictAll > caUnknown then
Exit;
Master := aMainRecord.MasterOrSelf;
if (Master.OverrideCount = 0) and not wbTranslationMode and not (Master.Signature = 'GMST') then begin
aConflictAll := caOnlyOne;
aConflictThis := ctOnlyOne;
aMainRecord.ConflictAll := aConflictAll;
aMainRecord.ConflictThis := aConflictThis;
end else begin
NodeDatas := NodeDatasForMainRecord(aMainRecord);
if Length(NodeDatas) = 1 then begin
aConflictAll := caOnlyOne;
NodeDatas[0].ConflictAll := caOnlyOne;
NodeDatas[0].ConflictThis := ctOnlyOne;
{end else if wbQuickShowConflicts and (Length(NodeDatas) = 2) then begin
aConflictAll := caOverride;
NodeDatas[0].ConflictAll := caOverride;
NodeDatas[1].ConflictAll := caOverride;
NodeDatas[0].ConflictThis := ctMaster;
NodeDatas[1].ConflictThis := ctOverride;}
end else
aConflictAll := ConflictLevelForChildNodeDatas(NodeDatas, False, (aMainRecord.MasterOrSelf.IsInjected and not (aMainRecord.Signature = 'GMST')) );
for i := Low(NodeDatas) to High(NodeDatas) do
with NodeDatas[i] do
if Assigned(Element) then
with (Element as IwbMainRecord) do begin
ConflictAll := aConflictAll;
ConflictThis := NodeDatas[i].ConflictThis;
end;
Fix(Master);
for i := 0 to Pred(Master.OverrideCount) do
Fix(Master.Overrides[i]);
aConflictThis := aMainRecord.ConflictThis;
end;
end;
procedure InitChilds(const aNodeDatas: PViewNodeDatas; aNodeCount: Integer;
var aChildCount: Cardinal);
var
NodeData : PNavNodeData;
Container : IwbContainer;
FirstContainer : IwbContainer;
SortableContainer : IwbSortableContainer;
Element : IwbElement;
i, j, k : Integer;
SortedCount : Integer;
NonSortedCount : Integer;
SortedKeys : array of TnxFastStringListCS;
Sortables : array of IwbSortableContainer;
SortKey : string;
LastSortKey : string;
DupCounter : Integer;
begin
SortedCount := 0;
NonSortedCount := 0;
FirstContainer := nil;
for i := 0 to Pred(aNodeCount) do begin
NodeData := @aNodeDatas[i];
Container := NodeData.Container;
if not Assigned(FirstContainer) then
FirstContainer := Container;
if Assigned(Container) then
if Supports(Container, IwbSortableContainer, SortableContainer) and SortableContainer.Sorted then
Inc(SortedCount)
else
Inc(NonSortedCount);
end;
if (NonSortedCount > 0) and (SortedCount > 0) then begin
if Assigned(FirstContainer) then
;//PostAddMessage('Warning: Comparing sorted and unsorted entry for "' + FirstContainer.Path + '" in "'+FirstContainer.ContainingMainRecord.Name+'"');
SortedCount := 0;
end;
if SortedCount > 0 then begin
// Assert(NonSortedCount = 0);
SetLength(SortedKeys, Succ(aNodeCount));
for i := Low(SortedKeys) to High(SortedKeys) do begin
SortedKeys[i] := TnxFastStringListCS.Create;
SortedKeys[i].Sorted := True;
SortedKeys[i].Duplicates := dupError;
end;
try
SortedKeys[aNodeCount].Duplicates := dupIgnore;
SetLength(Sortables, aNodeCount);
for i := 0 to Pred(aNodeCount) do
if Supports(aNodeDatas[i].Container, IwbSortableContainer, Sortables[i]) then begin
SortableContainer := Sortables[i];
DupCounter := 0;
LastSortKey := '';
for j := 0 to Pred(SortableContainer.ElementCount) do begin
Element := SortableContainer.Elements[j];
SortKey := Element.SortKey[False];
if SameStr(LastSortKey, SortKey) then
Inc(DupCounter)
else begin
DupCounter := 0;
LastSortKey := SortKey;
end;
SortKey := SortKey + '<' + IntToHex64(DupCounter, 4) + '>';
SortedKeys[i].AddObject(SortKey, Pointer(Element));
SortedKeys[aNodeCount].Add(SortKey);
end;
end;
aChildCount := SortedKeys[aNodeCount].Count;
for j := 0 to Pred(aChildCount) do begin
SortKey := SortedKeys[aNodeCount].Strings[j];
for i := 0 to Pred(aNodeCount) do
if SortedKeys[i].Find(SortKey, k) then
IwbElement(Pointer(SortedKeys[i].Objects[k])).SortOrder := j;
end;
finally
for i := Low(SortedKeys) to High(SortedKeys) do
FreeAndNil(SortedKeys[i]);
end;
end
else
for i := 0 to Pred(aNodeCount) do begin
NodeData := @aNodeDatas[i];
Container := NodeData.Container;
if Assigned(Container) then begin
case Container.ElementType of
etMainRecord, etSubRecordStruct: begin
aChildCount := (Container.Def as IwbRecordDef).MemberCount;
Inc(aChildCount, Container.AdditionalElementCount);
if Cardinal(Container.ElementCount) > aChildCount then begin
//PostAddMessage('Error: Container.ElementCount {'+IntToStr(Container.ElementCount)+'} > aChildCount {'+IntToStr(aChildCount)+'} for ' + Container.Path + ' in ' + Container.ContainingMainRecord.Name);
//for j := 0 to Pred(Container.ElementCount) do
//PostAddMessage(' #'+IntToStr(j)+': ' + Container.Elements[j].Name);
//Assert(Cardinal(Container.ElementCount) <= aChildCount);
end;
end;
etSubRecordArray, etArray, etStruct, etSubRecord, etValue, etUnion, etStructChapter:
if aChildCount < Cardinal(Container.ElementCount) then
aChildCount := Container.ElementCount;
end;
end;
end;
end;
procedure InitNodes(const aNodeDatas: PViewNodeDatas;
const aParentDatas: PViewNodeDatas;
aNodeCount: Integer;
aIndex: Cardinal;
var aInitialStates: TVirtualNodeInitStates);
var
NodeData : PViewNodeData;
ParentData : PViewNodeData;
Container : IwbContainerElementRef;
SortableContainer : IwbSortableContainer;
i : Integer;
begin
for i := 0 to Pred(aNodeCount) do begin
NodeData := @aNodeDatas[i];
ParentData := @aParentDatas[i];
Container := ParentData.Container;
if Assigned(Container) then begin
if Supports(Container, IwbSortableContainer, SortableContainer) and SortableContainer.Sorted then
NodeData.Element := Container.ElementBySortOrder[aIndex]
else
case Container.ElementType of
etMainRecord, etSubRecordStruct:
NodeData.Element := Container.ElementBySortOrder[aIndex];
etSubRecordArray, etArray, etStruct, etSubRecord, etValue, etUnion, etStructChapter:
if aIndex < Cardinal(Container.ElementCount) then
NodeData.Element := Container.Elements[aIndex];
end;
end;
if Assigned(NodeData.Element) and NodeData.Element.DontShow then begin
NodeData.Element := nil;
Include(NodeData.ViewNodeFlags, vnfDontShow);
end;
end;
aInitialStates := [ivsDisabled];
for i := 0 to Pred(aNodeCount) do
with aNodeDatas[i] do begin
if Assigned(Element) then
Exclude(aInitialStates, ivsDisabled)
else
if Assigned(aParentDatas) and ((vnfIgnore in aParentDatas[i].ViewNodeFlags) or (Assigned(aParentDatas[i].Element) and (aParentDatas[i].Element.ConflictPriority = cpIgnore))) then
Include(ViewNodeFlags, vnfIgnore);
if not Assigned(Container) then
if Supports(Element, IwbContainerElementRef, Container) then begin
// if Container.ElementCount = 0 then
// Container := nil;
end;
if Assigned(Container) then
if Container.ElementCount > 0 then
Include(aInitialStates, ivsHasChildren);
end;
end;
function ConflictLevelForChildNodeDatas(const aNodeDatas: TDynViewNodeDatas;
aSiblingCompare, aInjected: Boolean): TConflictAll;
var
ChildCount : Cardinal;
i, j : Integer;
NodeDatas : TDynViewNodeDatas;
InitialStates : TVirtualNodeInitStates;
ConflictAll : TConflictAll;
ConflictThis : TConflictThis;
Element : IwbElement;
begin
case Length(aNodeDatas) of
0: Result := caUnknown;
1: begin
Result := caOnlyOne;
aNodeDatas[0].ConflictThis := ctOnlyOne;
end;
else
Result := caNoConflict;
end;
if wbTranslationMode then begin
if Result < caOnlyOne then
Exit;
end
else begin
if Result < caNoConflict then
Exit;
end;
ChildCount := 0;
InitChilds(@aNodeDatas[0], Length(aNodeDatas), ChildCount);
if ChildCount > 0 then
for i := 0 to Pred(ChildCount) do begin
NodeDatas := nil;
SetLength(NodeDatas, Length(aNodeDatas));
InitialStates := [];
InitNodes(@NodeDatas[0], @aNodeDatas[0], Length(aNodeDatas), i, InitialStates);
if not (ivsDisabled in InitialStates) then begin
if ivsHasChildren in InitialStates then
ConflictAll := ConflictLevelForChildNodeDatas(NodeDatas, aSiblingCompare, aInjected)
else
ConflictAll := ConflictLevelForNodeDatas(@NodeDatas[0], Length(NodeDatas), aSiblingCompare, aInjected);
if ConflictAll > Result then
Result := ConflictAll;
for j := Low(aNodeDatas) to High(aNodeDatas) do
if NodeDatas[j].ConflictThis > aNodeDatas[j].ConflictThis then
aNodeDatas[j].ConflictThis := NodeDatas[j].ConflictThis;
end
else begin
ConflictThis := ctNotDefined;
for j := Low(aNodeDatas) to High(aNodeDatas) do begin
Element := aNodeDatas[j].Container;
if Assigned(Element) then
Break;
end;
if Assigned(Element) and (Element.ElementType in [etMainRecord, etSubRecordStruct]) then begin
j := (Element as IwbContainer).AdditionalElementCount;
if i >= j then
with (Element.Def as IwbRecordDef).Members[i - j] do
if (wbTranslationMode and (ConflictPriority[nil] <> cpTranslate)) or
(wbTranslationMode and (ConflictPriority[nil] = cpIgnore)) then
ConflictThis := ctIgnored;
end;
for j := Low(aNodeDatas) to High(aNodeDatas) do
if ConflictThis > aNodeDatas[j].ConflictThis then
aNodeDatas[j].ConflictThis := ConflictThis;
end;
end;
end;
function ConflictLevelForNodeDatas(const aNodeDatas: PViewNodeDatas;
aNodeCount: Integer; aSiblingCompare, aInjected: Boolean): TConflictAll;
var
Element : IwbElement;
CompareElement : IwbElement;
i, j : Integer;
UniqueValues : TnxFastStringListCS;
MasterPosition : Integer;
FirstElement : IwbElement;
FirstElementNotIgnored : IwbElement;
LastElement : IwbElement;
SameAsLast : Boolean;
SameAsFirst : Boolean;
OverallConflictThis : TConflictThis;
Priority : TwbConflictPriority;
ThisPriority : TwbConflictPriority;
FoundAny : Boolean;
begin
// if aSiblingCompare then
// Priority := cpBenign
// else
// Priority := cpNormal;
// IgnoreConflicts := False;
FoundAny := False;
MasterPosition := 0;
OverallConflictThis := ctUnknown;
case aNodeCount of
0: Result := caUnknown;
1: begin
Element := aNodeDatas[0].Element;
if Assigned(Element) then begin
if Element.ConflictPriority = cpIgnore then
aNodeDatas[0].ConflictThis := ctIgnored
else
aNodeDatas[0].ConflictThis := ctOnlyOne;
end else
aNodeDatas[0].ConflictThis := ctNotDefined;
Result := caOnlyOne;
end
else
LastElement := aNodeDatas[Pred(aNodeCount)].Element;
FirstElement := aNodeDatas[0].Element;
UniqueValues := TnxFastStringListCS.Create;
UniqueValues.Sorted := True;
UniqueValues.Duplicates := dupIgnore;
Priority := cpNormal;
try
for i := 0 to Pred(aNodeCount) do begin
Element := aNodeDatas[i].Element;
if Assigned(Element) then begin
FoundAny := True;
Priority := Element.ConflictPriority;
if Priority = cpNormalIgnoreEmpty then begin
FirstElement := Element;
MasterPosition := i;
for j := Pred(aNodeCount) downto i do begin
LastElement := aNodeDatas[j].Element;
if Assigned(LastElement) then
Break;
end;
end;
if Element.ConflictPriorityCanChange then begin
for j := Succ(i) to Pred(aNodeCount) do begin
Element := aNodeDatas[j].Element;
if Assigned(Element) then begin
ThisPriority := Element.ConflictPriority;
if ThisPriority > Priority then
Priority := ThisPriority;
end;
end;
end;
Break;
end;
end;
if aSiblingCompare then
if Priority > cpBenign then
Priority := cpBenign;
if aInjected and (Priority >= cpNormal) then
Priority := cpCritical;
if (Priority > cpIgnore) and (not Assigned(FirstElement) or (FirstElement.ConflictPriority = cpIgnore)) then
FirstElementNotIgnored := nil
else
FirstElementNotIgnored := FirstElement;
for i := 0 to Pred(aNodeCount) do begin
Element := aNodeDatas[i].Element;
if Assigned(Element) then begin
ThisPriority := Element.ConflictPriority;
if ThisPriority <> cpIgnore then
UniqueValues.Add(Element.SortKey[True]);
end else begin
ThisPriority := Priority;
if not (vnfIgnore in aNodeDatas[i].ViewNodeFlags) then
if Priority <> cpNormalIgnoreEmpty then
UniqueValues.Add('');
end;
if (ThisPriority = cpNormalIgnoreEmpty) and not Assigned(Element) then
aNodeDatas[i].ConflictThis := ctIgnored
else if ThisPriority = cpIgnore then
aNodeDatas[i].ConflictThis := ctIgnored
else if aSiblingCompare then
aNodeDatas[i].ConflictThis := ctOnlyOne
else if i = MasterPosition then begin
if Assigned(Element) then
aNodeDatas[i].ConflictThis := ctMaster
else
aNodeDatas[i].ConflictThis := ctUnknown;
end else begin
SameAsLast := (i = Pred(aNodeCount)) or not (
(Assigned(Element) <> Assigned(LastElement)) or
(Assigned(Element) and not SameStr(Element.SortKey[True], LastElement.SortKey[True]))
);
SameAsFirst := not (
(Assigned(Element) <> Assigned(FirstElementNotIgnored)) or
(Assigned(Element) and not SameStr(Element.SortKey[True], FirstElementNotIgnored.SortKey[True]))
);
if not SameAsFirst and
(ThisPriority = cpBenignIfAdded) and
SameAsLast and // We are not overriden later
not Assigned(FirstElementNotIgnored) then begin // The master did not have that element
ThisPriority := cpBenign;
Priority := cpBenign;
SameAsFirst := True;
end;
if SameAsFirst then
aNodeDatas[i].ConflictThis := ctIdenticalToMaster
else if SameAsLast then
aNodeDatas[i].ConflictThis := ctConflictWins
else
aNodeDatas[i].ConflictThis := ctConflictLoses;
end;
if (ThisPriority = cpBenign) and (aNodeDatas[i].ConflictThis > ctConflictBenign) then
aNodeDatas[i].ConflictThis := ctConflictBenign;
if aNodeDatas[i].ConflictThis > OverallConflictThis then
OverallConflictThis := aNodeDatas[i].ConflictThis;
end;
case UniqueValues.Count of
0: Result := caNoConflict;
1: Result := caNoConflict;
2: begin
Element := aNodeDatas[0].Element;
CompareElement := aNodeDatas[Pred(aNodeCount)].Element;
if (Assigned(Element) <> Assigned(CompareElement)) or
(Assigned(Element) and not SameStr(Element.SortKey[True], CompareElement.SortKey[True])) then
Result := caOverride
else if (UniqueValues.IndexOf('') >= 0) and Assigned(CompareElement) and (CompareElement.SortKey[True] <> '') then
Result := caOverride
else
Result := caConflict;
end
else
Result := caConflict;
end;
if aSiblingCompare and (Result > caConflictBenign) then
Result := caConflictBenign;
if not FoundAny then
for i := 0 to Pred(aNodeCount) do
aNodeDatas[i].ConflictThis := ctNotDefined;
if Result > caNoConflict then
case Priority of
cpBenign: Result := caConflictBenign;
cpCritical: begin
if UniqueValues.Find('', i) then
UniqueValues.Delete(i);
if UniqueValues.Count > 1 then
Result := caConflictCritical;
end;
end;
if Priority > cpBenign then
if OverallConflictThis > ctOverride then
with aNodeDatas[Pred(aNodeCount)] do
if ConflictThis < ctOverride then
if ConflictThis = ctIdenticalToMaster then
ConflictThis := ctIdenticalToMasterWinsConflict
else
ConflictThis := ctConflictWins;
if Result in [caNoConflict, caOverride, caConflict] then
for i := 0 to Pred(aNodeCount) do begin
case aNodeDatas[i].ConflictThis of
ctIdenticalToMaster: case Result of
caNoConflict: ;
caOverride, caConflict: if i = Pred(aNodeCount) then
aNodeDatas[i].ConflictThis := ctIdenticalToMasterWinsConflict
end;
ctConflictWins: case Result of
caNoConflict: aNodeDatas[i].ConflictThis := ctIdenticalToMaster;
caOverride: aNodeDatas[i].ConflictThis := ctOverride;
caConflict: ;
end;
end;
end;
if Result < caConflict then
for i := 0 to Pred(aNodeCount) do
if aNodeDatas[i].ConflictThis >= ctIdenticalToMasterWinsConflict then begin
Result := caConflict;
Break;
end;
finally
FreeAndNil(UniqueValues);
end;
end;
end;
function ConflictThisForMainRecord(aMainRecord: IwbMainRecord): TConflictThis;
var
ct: TConflictThis;
ca: TConflictAll;
begin
ConflictLevelForMainRecord(aMainRecord, ca, ct);
Result := ct;
end;
function ConflictAllForMainRecord(aMainRecord: IwbMainRecord): TConflictAll;
var
ct: TConflictThis;
ca: TConflictAll;
begin
ConflictLevelForMainRecord(aMainRecord, ca, ct);
Result := ca;
end;
function IsITPO(rec: IwbMainRecord): Boolean;
var
mRec, prevOvr, ovr: IwbMainRecord;
i: Integer;
begin
// get previous override
mRec := rec.MasterOrSelf;
prevovr := mRec;
for i := 0 to Pred(mRec.OverrideCount) do begin
ovr := mRec.Overrides[i];
if ovr.Equals(rec) then
Break;
prevovr := ovr;
end;
Result := ConflictAllForElements(prevovr, rec, False, False) <= caNoConflict;
end;
function IsITM(rec: IwbMainRecord): Boolean;
const
ITMConflictArray: set of TConflictThis = [
ctIdenticalToMaster,
ctIdenticalToMasterWinsConflict
];
begin
Result := ConflictThisForMainRecord(rec) in ITMConflictArray;
end;
end.
================================================
FILE: frontend/msConflictForm.dfm
================================================
object ConflictForm: TConflictForm
Left = 0
Top = 0
Caption = 'Combine smash settings'
ClientHeight = 377
ClientWidth = 709
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnClose = FormClose
OnCreate = FormCreate
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object btnOK: TButton
Left = 545
Top = 344
Width = 75
Height = 25
Align = alCustom
Anchors = [akRight, akBottom]
Caption = 'OK'
TabOrder = 0
OnClick = btnOKClick
end
object btnCancel: TButton
Left = 626
Top = 344
Width = 75
Height = 25
Align = alCustom
Anchors = [akRight, akBottom]
Caption = 'Cancel'
ModalResult = 2
TabOrder = 1
end
object tvRecords: TTreeView
Left = 301
Top = 8
Width = 400
Height = 330
Align = alCustom
Anchors = [akTop, akRight, akBottom]
DoubleBuffered = True
Indent = 19
MultiSelect = True
ParentDoubleBuffered = False
ReadOnly = True
StateImages = StateImages
TabOrder = 2
OnCustomDrawItem = tvRecordsCustomDrawItem
OnMouseMove = tvRecordsMouseMove
end
object sbChoices: TScrollBox
Left = 8
Top = 8
Width = 287
Height = 330
Align = alCustom
Anchors = [akLeft, akTop, akRight, akBottom]
TabOrder = 3
end
object FlagIcons: TImageList
Left = 408
Top = 24
Bitmap = {
494C010103000800540010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600
0000000000003600000028000000400000001000000001002000000000000010
0000000000000000000000000000000000000000000000000000000000000000
0000D7D7F8FF7373E6FF3434DBFF2121BEFF2121BEFF2D2DDAFF6B6BE4FFD2D2
F7FF000000000000000000000000000000000000000000000000000000000000
0000E4F1E779D7D6B8CCD4BF91F3D2B683FED2B581FED1BD8FF3D5D3B5CCE3F0
E6790000000000000000000000000000000000000000D1D1D12E4F4F4FB01B1B
1BE42B2B2BD48282827DF7F7F708000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000F8F8FDFF7373
E6FF2020B5FF2020B5FF3434DBFF5B5BE2FF5B5BE2FF3D3DDCFF2020B5FF2020
B5FF6464E3FFF8F8FDFF00000000000000000000000000000000F2F8F33CD9D8
BACBDCAB6CFEE1974BFFE18F3DFFE18A37FFDF8835FFDD8A39FFD99044FFD4A3
64FED4D4B6CBF1F7F23C0000000000000000D1D1D12E0C0C0CF3000000FF0000
00FF000000FF000000FF3B3B3BC4F2F2F20D0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000F8F8FDFF4242DDFF2020
B5FF5353E0FFD7D7F8FF00000000000000000000000000000000E2E2F9FF5B5B
E2FF2020B5FF3D3DDCFFEFEFFCFF0000000000000000F2F8F33CDBCDA5DEE3A1
58FFE69240FFE58F3AFFE48D39FFE28B37FFE08A36FFDF8834FFDD8733FFDB87
35FFD7944CFFD3C49DDEF1F7F23C000000004E4E4EB1000000FF4D4D4DB2D7D7
D728B2B2B24D1A1A1AE5000000FF3A3A3AC5F2F2F20D00000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000007373E6FF2020B5FF8282
E9FF000000000000000000000000FEFEFE03FDFDFE0700000000000000000000
00009292EBFF2020B5FF6464E3FF0000000000000000DBDABCCBE6A35AFFE994
41FFE8923EFFE7903CFFE58E3AFFE38D38FFE28B37FFE08935FFDF8834FFDD86
32FFDC8633FFD6944BFFD4D3B5CB000000001B1B1BE4000000FFD7D7D7280000
000000000000D9D9D9261B1B1BE4000000FF3A3A3AC5F2F2F20D000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000D7D7F8FF2020B5FF5353E0FF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000006464E3FF2020B5FFC8C8F5FFE6F3E879E3B273FEEC9846FFEB95
41FFEA933FFFE8913DFFEAA560FFF9F7F5FFF8F0E8FFE18B37FFE08935FFDE88
33FFDD8632FFDA8735FFD3A263FEE3F0E6792B2B2BD4000000FFB3B3B34C0000
00000000000000000000D9D9D926BABABA45EFEFEF10F3F3F30C000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000007A7AE7FF2020B5FFD2D2F7FF0000
00000000000000000000FEFEFE0D0000000000000000F4F4FC28000000000000
000000000000E2E2F9FF2020B5FF6B6BE4FFDDDBBDCCEBA256FFEE9844FFED96
42FFEB9440FFE9933FFFEBA562FFF9F7F5FFF8F0E8FFE38C38FFE18A36FFE089
35FFDE8733FFDD8632FFD88F43FFD4D3B5CC8383837C000000FF1A1A1AE5D9D9
D9260000000000000000C3C3C33C424242BD131313EC262626D97F7F7F80F7F7
F708000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003434DBFF3434DBFF000000000000
0000B9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9F2FFB9B9
F2FFEFEFFCFF000000004242DDFF2525D6FFDDC89AF3F09D4BFFF09945FFEE97
43FFED9642FFEB9440FFECA663FFF9F7F5FFF8F0E9FFE48D39FFE28C38FFE18A
36FFDF8934FFDE8733FFDB8937FFD1BC8DF3F7F7F7083B3B3BC4000000FF1B1B
1BE4D9D9D926E3E3E31C060606F9000000FF000000FF000000FF000000FF3B3B
3BC4F2F2F20D0000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002323C6FF5353E0FF000000000000
00002121BEFF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020
B5FFC8C8F5FF000000006464E3FF2121BEFFDFC38FFEF39C49FFF19A46FFEF99
44FFEE9743FFEC9541FFEEA864FFF9F7F5FFF8F0E9FFE68F3BFFE48D39FFE28B
37FFE18A36FFDF8834FFDD8734FFD0B480FE00000000F2F2F20D3A3A3AC50000
00FF1B1B1BE4CECECE31444444BB7171718EE1E1E11EB7B7B7481A1A1AE50000
00FF3A3A3AC5F2F2F20D00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000002323C6FF5353E0FF000000000000
00002020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020B5FF2020
B5FFC8C8F5FF000000006464E3FF2121BEFFE0C390FEF49D4AFFF29B47FFF19A
46FFEF9844FFEE9743FFEFA965FFF9F7F5FFF8F0E9FFE7903CFFE58E3AFFE48D
39FFE28B37FFE08A35FFDF8835FFD1B581FE0000000000000000F2F2F20D3A3A
3AC5000000FF1A1A1AE5B8B8B847E1E1E11E7171718E444444BBCECECE311B1B
1BE4000000FF3A3A3AC5F2F2F20D000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000003D3DDCFF2D2DDAFF000000000000
0000F8F8FDFFF8F8FDFFEFEFFCFFEFEFFCFFEFEFFCFFEFEFFCFFEFEFFCFFF8F8
FDFFF8F8FDFF000000003D3DDCFF2525D6FFDFCA9CF3F3A14FFFF39D48FFF29B
47FFF09A45FFEF9844FFF0B172FFF9F7F5FFF8F0E9FFE8913DFFE7903CFFE58E
3AFFE38C38FFE28B37FFDF8C3BFFD2BE90F3000000000000000000000000F2F2
F20D3B3B3BC4000000FF000000FF000000FF000000FF060606F9E3E3E31CD9D9
D9261B1B1BE4000000FF3B3B3BC4F7F7F7080000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000007373E6FF2020B5FFD2D2F7FF0000
0000000000000000000000000000F1F1FA0FFAFAFD05F1F1FC32000000000000
000000000000E2E2F9FF2020B5FF6B6BE4FFDFDDBFCCF1A85BFFF49E4AFFF39C
48FFF29B47FFF5CBA3FFF9F7F5FFF9F7F5FFF8F0E9FFEA933FFFE8913DFFE68F
3BFFE58E3AFFE38C38FFDE9548FFD7D5B7CC0000000000000000000000000000
0000F7F7F7087F7F7F80262626D9131313EC424242BDC3C3C33C000000000000
0000D9D9D9261A1A1AE5000000FF8383837C0000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000D7D7F8FF2020B5FF5353E0FF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000006464E3FF2020B5FFC8C8F5FFE7F3E979E9B879FEF4A14FFFF49D
49FFF39C48FFF19B46FFF19F51FFF6DEC6FFF8F1E9FFEB9440FFE9933EFFE891
3DFFE68F3BFFE3903DFFDAA96AFEE4F1E7790000000000000000000000000000
00000000000000000000F3F3F30CEFEFEF10BABABA45D9D9D926000000000000
000000000000B3B3B34C000000FF2C2C2CD30000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000007A7AE7FF2020B5FF8282
E9FF000000000000000000000000000000000000000000000000000000000000
00008B8BEAFF2020B5FF6464E3FF0000000000000000DFDEC0CBEFAD64FFF4A0
4CFFF49D49FFF39C48FFF19A46FFF09945FFEE9743FFEC9641FFEB9440FFE992
3EFFE7913EFFE19E55FFD8D7B9CB000000000000000000000000000000000000
00000000000000000000F
gitextract_wihtrx14/
├── .gitignore
├── ESPs/
│ ├── SmashTestPlugin01.esp
│ ├── SmashTestPlugin02.esp
│ └── SmashTestPlugin03.esp
├── LICENSE.txt
├── README.md
├── design/
│ ├── code snippets/
│ │ ├── GetMasterElement.pas
│ │ ├── Mator Smash v0.9.pas
│ │ └── better build algorithm.pas
│ ├── diagrams/
│ │ └── Mator Smash.vpp
│ └── notes/
│ ├── algorithm problems.txt
│ ├── handling.txt
│ ├── high level design.txt
│ ├── linking explanation.txt
│ └── todos 1024.txt
├── frontend/
│ ├── MatorSmash.dpr
│ ├── MatorSmash.dproj
│ ├── MatorSmash.mes
│ ├── MatorSmash.res
│ ├── ModelSupport_MatorSmash/
│ │ ├── MatorSmash/
│ │ │ └── default.txvpck
│ │ ├── default.txvpck
│ │ ├── msEditForm/
│ │ │ └── default.txvpck
│ │ ├── msFrontend/
│ │ │ └── default.txvpck
│ │ ├── msOptionsForm/
│ │ │ └── default.txvpck
│ │ ├── msProfileForm/
│ │ │ └── default.txvpck
│ │ ├── msProfilePanel/
│ │ │ └── default.txvpck
│ │ ├── msSmashForm/
│ │ │ └── default.txvpck
│ │ ├── msSplashForm/
│ │ │ └── default.txvpck
│ │ └── msThreads/
│ │ └── default.txvpck
│ ├── lang/
│ │ └── english.lang
│ ├── msAlgorithm.pas
│ ├── msChoicePanel.pas
│ ├── msConfiguration.pas
│ ├── msConflict.pas
│ ├── msConflictForm.dfm
│ ├── msConflictForm.pas
│ ├── msCore.pas
│ ├── msEditForm.dfm
│ ├── msEditForm.pas
│ ├── msLoader.pas
│ ├── msOptionsForm.dfm
│ ├── msOptionsForm.pas
│ ├── msPluginSelectionForm.dfm
│ ├── msPluginSelectionForm.pas
│ ├── msPriorityForm.dfm
│ ├── msPriorityForm.pas
│ ├── msProfileForm.dfm
│ ├── msProfileForm.pas
│ ├── msProfilePanel.pas
│ ├── msSettingsManager.dfm
│ ├── msSettingsManager.pas
│ ├── msSmash.pas
│ ├── msSmashForm.dfm
│ ├── msSmashForm.pas
│ ├── msSplashForm.dfm
│ ├── msSplashForm.pas
│ ├── msTagHelper.dfm
│ ├── msTagHelper.pas
│ ├── msTagManager.dfm
│ ├── msTagManager.pas
│ ├── msThreads.pas
│ ├── settings/
│ │ ├── Fallout3/
│ │ │ └── Smash.All.json
│ │ ├── Fallout4/
│ │ │ └── Smash.All.json
│ │ ├── FalloutNV/
│ │ │ └── Smash.All.json
│ │ ├── Oblivion/
│ │ │ ├── Bash.Actors.ACBS.json
│ │ │ ├── Bash.Actors.AIData.json
│ │ │ ├── Bash.Actors.AIPackages.json
│ │ │ ├── Bash.Actors.Animations.json
│ │ │ ├── Bash.Actors.CombatStyle.json
│ │ │ ├── Bash.Actors.DeathItem.json
│ │ │ ├── Bash.Actors.Skeleton.json
│ │ │ ├── Bash.Actors.Spells.json
│ │ │ ├── Bash.Actors.Stats.json
│ │ │ ├── Bash.Body-F.json
│ │ │ ├── Bash.Body-M.json
│ │ │ ├── Bash.Body-Size-F.json
│ │ │ ├── Bash.Body-Size-M.json
│ │ │ ├── Bash.C.Climate.json
│ │ │ ├── Bash.C.Light.json
│ │ │ ├── Bash.C.Music.json
│ │ │ ├── Bash.C.Name.json
│ │ │ ├── Bash.C.Owner.json
│ │ │ ├── Bash.C.RecordFlags.json
│ │ │ ├── Bash.C.Water.json
│ │ │ ├── Bash.Creatures.Blood.json
│ │ │ ├── Bash.Eyes.json
│ │ │ ├── Bash.Factions.json
│ │ │ ├── Bash.Graphics.json
│ │ │ ├── Bash.Hair.json
│ │ │ ├── Bash.Invent.json
│ │ │ ├── Bash.Lev.json
│ │ │ ├── Bash.NPC.Class.json
│ │ │ ├── Bash.NPC.Race.json
│ │ │ ├── Bash.Names.json
│ │ │ ├── Bash.Npc.EyesOnly.json
│ │ │ ├── Bash.Npc.HairOnly.json
│ │ │ ├── Bash.NpcFaces.json
│ │ │ ├── Bash.NpcFacesForceFullImport.json
│ │ │ ├── Bash.R.AddSpells.json
│ │ │ ├── Bash.R.Attributes-F.json
│ │ │ ├── Bash.R.Attributes-M.json
│ │ │ ├── Bash.R.ChangeSpells.json
│ │ │ ├── Bash.R.Description.json
│ │ │ ├── Bash.Relations.json
│ │ │ ├── Bash.Scripts.json
│ │ │ ├── Bash.Sound.json
│ │ │ ├── Bash.SpellStats.json
│ │ │ ├── Bash.Stats.json
│ │ │ ├── Bash.Voice-F.json
│ │ │ ├── Bash.Voice-M.json
│ │ │ └── Smash.All.json
│ │ └── Skyrim/
│ │ ├── Bash.Actors.ACBS.json
│ │ ├── Bash.Actors.AIData.json
│ │ ├── Bash.Actors.AIPackages.json
│ │ ├── Bash.Actors.AIPackagesMerge.json
│ │ ├── Bash.Actors.CombatStyle.json
│ │ ├── Bash.Actors.DeathItem.json
│ │ ├── Bash.Actors.Spells.json
│ │ ├── Bash.Actors.SpellsMerge.json
│ │ ├── Bash.Actors.Stats.json
│ │ ├── Bash.All.json
│ │ ├── Bash.Body-F.json
│ │ ├── Bash.Body-M.json
│ │ ├── Bash.Body-Size-F.json
│ │ ├── Bash.Body-Size-M.json
│ │ ├── Bash.C.Acoustic.json
│ │ ├── Bash.C.Climate.json
│ │ ├── Bash.C.Encounter.json
│ │ ├── Bash.C.ImageSpace.json
│ │ ├── Bash.C.Light.json
│ │ ├── Bash.C.Location.json
│ │ ├── Bash.C.Music.json
│ │ ├── Bash.C.Name.json
│ │ ├── Bash.C.Owner.json
│ │ ├── Bash.C.RecordFlags.json
│ │ ├── Bash.C.Regions.json
│ │ ├── Bash.C.Water.json
│ │ ├── Bash.Delev.json
│ │ ├── Bash.Eyes.json
│ │ ├── Bash.Factions.json
│ │ ├── Bash.Graphics.json
│ │ ├── Bash.Hairs.json
│ │ ├── Bash.Invent.json
│ │ ├── Bash.Lev.json
│ │ ├── Bash.NPC.Class.json
│ │ ├── Bash.NPC.Race.json
│ │ ├── Bash.Names.json
│ │ ├── Bash.NpcFaces.json
│ │ ├── Bash.NpcFacesForceFullImport.json
│ │ ├── Bash.R.AddSpells.json
│ │ ├── Bash.R.ChangeSpells.json
│ │ ├── Bash.R.Description.json
│ │ ├── Bash.R.Head.json
│ │ ├── Bash.R.Skills.json
│ │ ├── Bash.Relations.json
│ │ ├── Bash.Relev.json
│ │ ├── Bash.Scripts.json
│ │ ├── Bash.Sound.json
│ │ ├── Bash.SpellStats.json
│ │ ├── Bash.Stats.json
│ │ ├── Bash.Voice-F.json
│ │ ├── Bash.Voice-M.json
│ │ ├── Skip.json
│ │ ├── Smash.All.json
│ │ ├── Smash.ForceAll.json
│ │ └── Smash.OverrideAll.json
│ ├── smash.rc
│ └── smash.res
└── lib/
├── Imaging/
│ ├── Imaging.pas
│ ├── ImagingBitmap.pas
│ ├── ImagingCanvases.pas
│ ├── ImagingClasses.pas
│ ├── ImagingColors.pas
│ ├── ImagingComponents.pas
│ ├── ImagingDds.pas
│ ├── ImagingFormats.pas
│ ├── ImagingIO.pas
│ ├── ImagingNetworkGraphics.pas
│ ├── ImagingOptions.inc
│ ├── ImagingTarga.pas
│ ├── ImagingTypes.pas
│ ├── ImagingUtility.pas
│ └── ZLib/
│ ├── dzlib.pas
│ ├── imadler.pas
│ ├── iminfblock.pas
│ ├── iminfcodes.pas
│ ├── iminffast.pas
│ ├── iminftrees.pas
│ ├── iminfutil.pas
│ ├── impaszlib.pas
│ ├── imtrees.pas
│ ├── imzconf.inc
│ ├── imzdeflate.pas
│ ├── imzinflate.pas
│ ├── imzutil.pas
│ └── readme.txt
├── abbrevia/
│ ├── MPL-1_1.txt
│ ├── Readme.html
│ ├── WavPack License.txt
│ ├── examples/
│ │ └── Delphi/
│ │ ├── Abbrexam.dpr
│ │ ├── BaseDlgu.pas
│ │ ├── Basedlgu.dfm
│ │ ├── CabExt.dpr
│ │ ├── CabExt1.dfm
│ │ ├── CabExt1.pas
│ │ ├── CabFind.dpr
│ │ ├── CabFind1.dfm
│ │ ├── CabFind1.pas
│ │ ├── CabView.dpr
│ │ ├── CabView1.dfm
│ │ ├── CabView1.pas
│ │ ├── ComCtrlsDemo.dpr
│ │ ├── ComCtrlsMain.dfm
│ │ ├── ComCtrlsMain.pas
│ │ ├── CompPad.dpr
│ │ ├── Contents.dpr
│ │ ├── Demo.cab
│ │ ├── ExCBrows.dpr
│ │ ├── ExCBrowu.dfm
│ │ ├── ExCBrowu.pas
│ │ ├── ExCf.dpr
│ │ ├── ExCf.res
│ │ ├── ExFilter.dpr
│ │ ├── ExFiltru.dfm
│ │ ├── ExFiltru.pas
│ │ ├── ExZipper.dpr
│ │ ├── ExZippru.dfm
│ │ ├── ExZippru.pas
│ │ ├── FCITest1.dfm
│ │ ├── FCITest1.pas
│ │ ├── Finder.dpr
│ │ ├── MakeCab.dpr
│ │ ├── MakeCab1.dfm
│ │ ├── MakeCab1.pas
│ │ ├── SelfStbv.dpr
│ │ ├── SelfStub.dpr
│ │ ├── SlfStbv1.dfm
│ │ ├── SlfStbv1.pas
│ │ ├── Streams.dpr
│ │ ├── Streams1.dfm
│ │ ├── Streams1.pas
│ │ ├── StrmBmp.dpr
│ │ ├── StrmBmpU.dfm
│ │ ├── StrmBmpU.pas
│ │ ├── StrmPad.dpr
│ │ ├── TpZip.RC
│ │ ├── TpZip.dpr
│ │ ├── TpZip.r32
│ │ ├── TpZip31.HLP
│ │ ├── UContent.dfm
│ │ ├── UContent.pas
│ │ ├── UMain.dfm
│ │ ├── UMain.pas
│ │ ├── Uexample.dfm
│ │ ├── Uexample.pas
│ │ ├── Unzip.dpr
│ │ ├── Unzip.dproj
│ │ ├── Unzip.dproj.2007
│ │ ├── UsingApi.dpr
│ │ ├── Ustrpad.dfm
│ │ ├── Ustrpad.pas
│ │ ├── Uunzip.dfm
│ │ ├── Uunzip.pas
│ │ ├── Uzip.dfm
│ │ ├── Uzip.pas
│ │ ├── ZipReg.dpr
│ │ ├── ZipReg.dproj
│ │ ├── ZipReg.dproj.2007
│ │ ├── ZipReg1.dfm
│ │ ├── ZipReg1.pas
│ │ ├── ZipView.dpr
│ │ ├── ZipView1.dfm
│ │ ├── ZipView1.pas
│ │ ├── Zipper.dpr
│ │ ├── Zipper.dproj
│ │ ├── Zipper.dproj.2007
│ │ ├── dgAbout.dfm
│ │ ├── dgAbout.pas
│ │ ├── makesfx.dpr
│ │ ├── spntst0.dfm
│ │ ├── spntst0.pas
│ │ ├── uCfGenDg.dfm
│ │ ├── uCfGenDg.pas
│ │ ├── uCfMain.dfm
│ │ ├── uCfMain.pas
│ │ ├── uCfNewDg.dfm
│ │ ├── uCfNewDg.pas
│ │ ├── ubasedlg.dfm
│ │ ├── ubasedlg.pas
│ │ ├── ucomppad.dfm
│ │ ├── ucomppad.pas
│ │ ├── udemodlg.dfm
│ │ ├── udemodlg.pas
│ │ ├── ufinder.dfm
│ │ ├── ufinder.pas
│ │ ├── umakesfx.dfm
│ │ ├── umakesfx.pas
│ │ ├── usplash.dfm
│ │ └── usplash.pas
│ ├── localization/
│ │ ├── AbResString.pas.afr
│ │ ├── AbResString.pas.de
│ │ ├── AbResString.pas.fr
│ │ ├── AbResString.pas.nl
│ │ ├── AbResString.pas.ru
│ │ └── AbResString.pas.tr
│ ├── packages/
│ │ ├── Delphi XE/
│ │ │ ├── Abbrevia.dpk
│ │ │ ├── Abbrevia.dproj
│ │ │ ├── Abbrevia.res
│ │ │ ├── AbbreviaVCL.dpk
│ │ │ ├── AbbreviaVCL.dproj
│ │ │ ├── AbbreviaVCL.res
│ │ │ ├── AbbreviaVCLDesign.dpk
│ │ │ ├── AbbreviaVCLDesign.dproj
│ │ │ └── AbbreviaVCLDesign.res
│ │ └── Delphi XE.groupproj
│ └── source/
│ ├── AbArcTyp.pas
│ ├── AbBase.pas
│ ├── AbBitBkt.pas
│ ├── AbBrowse.pas
│ ├── AbBseCLX.pas
│ ├── AbBseVCL.pas
│ ├── AbBzip2.pas
│ ├── AbBzip2Typ.pas
│ ├── AbCBrows.pas
│ ├── AbCView.pas
│ ├── AbCabExt.pas
│ ├── AbCabKit.pas
│ ├── AbCabMak.pas
│ ├── AbCabTyp.pas
│ ├── AbCharset.pas
│ ├── AbComCtrls.pas
│ ├── AbComCtrls.res
│ ├── AbCompnd.pas
│ ├── AbConst.pas
│ ├── AbCrtl.pas
│ ├── AbDefine.inc
│ ├── AbDfBase.pas
│ ├── AbDfCryS.pas
│ ├── AbDfDec.pas
│ ├── AbDfEnc.pas
│ ├── AbDfHufD.pas
│ ├── AbDfInW.pas
│ ├── AbDfOutW.pas
│ ├── AbDfPkMg.pas
│ ├── AbDfStrm.pas
│ ├── AbDfXlat.pas
│ ├── AbDlgDir.dfm
│ ├── AbDlgDir.pas
│ ├── AbDlgPwd.dfm
│ ├── AbDlgPwd.pas
│ ├── AbExcept.pas
│ ├── AbFciFdi.pas
│ ├── AbGzTyp.pas
│ ├── AbHexVw.pas
│ ├── AbLZMA.pas
│ ├── AbLZMAStream.pas
│ ├── AbMeter.pas
│ ├── AbPPMd.pas
│ ├── AbPeCol.dfm
│ ├── AbPeCol.pas
│ ├── AbPeDir.pas
│ ├── AbPeFn.pas
│ ├── AbPePass.pas
│ ├── AbPeVer.dfm
│ ├── AbPeVer.pas
│ ├── AbQCView.pas
│ ├── AbQCmpnd.pas
│ ├── AbQDgDir.pas
│ ├── AbQDgDir.xfm
│ ├── AbQDgPwd.pas
│ ├── AbQDgPwd.xfm
│ ├── AbQHexVw.pas
│ ├── AbQMeter.pas
│ ├── AbQPeCol.pas
│ ├── AbQPeCol.xfm
│ ├── AbQPeDir.pas
│ ├── AbQPeFn.pas
│ ├── AbQPePas.pas
│ ├── AbQPeVer.pas
│ ├── AbQPeVer.xfm
│ ├── AbQView.pas
│ ├── AbQZView.pas
│ ├── AbQZpOut.pas
│ ├── AbReg.pas
│ ├── AbReg.res
│ ├── AbRegClx.pas
│ ├── AbRegLinux.pas
│ ├── AbRegVcl.pas
│ ├── AbResString.pas
│ ├── AbSWStm.pas
│ ├── AbSelfEx.pas
│ ├── AbSpanSt.pas
│ ├── AbTarTyp.pas
│ ├── AbUnzOutStm.pas
│ ├── AbUnzPrc.pas
│ ├── AbUnzper.pas
│ ├── AbUtils.pas
│ ├── AbVMStrm.pas
│ ├── AbView.pas
│ ├── AbWavPack.pas
│ ├── AbZBrows.pas
│ ├── AbZLTyp.pas
│ ├── AbZView.pas
│ ├── AbZipExt.pas
│ ├── AbZipKit.pas
│ ├── AbZipOut.pas
│ ├── AbZipOut.res
│ ├── AbZipPrc.pas
│ ├── AbZipTyp.pas
│ ├── AbZipper.pas
│ ├── COM/
│ │ ├── Abbrevia.dpr
│ │ ├── Abbrevia.dproj
│ │ ├── Abbrevia.res
│ │ ├── Abbrevia.ridl
│ │ ├── Abbrevia.tlb
│ │ ├── Abbrevia_TLB.pas
│ │ ├── Readme.txt
│ │ ├── _GZipItem.pas
│ │ ├── _TarItem.pas
│ │ ├── _ZipItem.pas
│ │ └── _ZipKit.pas
│ ├── Win32/
│ │ ├── CarrylessRangeCoder.obj
│ │ ├── LzFind.obj
│ │ ├── LzFindMt.obj
│ │ ├── LzmaDec.obj
│ │ ├── LzmaEnc.obj
│ │ ├── PPMdContext.obj
│ │ ├── PPMdSubAllocatorVariantI.obj
│ │ ├── PPMdVariantI.obj
│ │ ├── Threads.obj
│ │ ├── blocksort.obj
│ │ ├── bzlib.obj
│ │ ├── compress.obj
│ │ ├── decompress.obj
│ │ ├── huffman.obj
│ │ ├── wv_bits.obj
│ │ ├── wv_extra1.obj
│ │ ├── wv_extra2.obj
│ │ ├── wv_float.obj
│ │ ├── wv_metadata.obj
│ │ ├── wv_pack.obj
│ │ ├── wv_tags.obj
│ │ ├── wv_unpack.obj
│ │ ├── wv_unpack3.obj
│ │ ├── wv_words.obj
│ │ └── wv_wputils.obj
│ └── Win64/
│ ├── CarrylessRangeCoder.obj
│ ├── LzFind.obj
│ ├── LzFindMt.obj
│ ├── LzmaDec.obj
│ ├── LzmaEnc.obj
│ ├── PPMdContext.obj
│ ├── PPMdSubAllocatorVariantI.obj
│ ├── PPMdVariantI.obj
│ ├── Threads.obj
│ ├── blocksort.obj
│ ├── bzlib.obj
│ ├── compress.obj
│ ├── decompress.obj
│ ├── huffman.obj
│ ├── wv_bits.obj
│ ├── wv_extra1.obj
│ ├── wv_extra2.obj
│ ├── wv_float.obj
│ ├── wv_metadata.obj
│ ├── wv_pack.obj
│ ├── wv_tags.obj
│ ├── wv_unpack.obj
│ ├── wv_unpack3.obj
│ ├── wv_words.obj
│ └── wv_wputils.obj
├── mte/
│ ├── CRC32.pas
│ ├── RttiIni.pas
│ ├── RttiJson.pas
│ ├── RttiTranslation.pas
│ ├── W7Taskbar.pas
│ ├── mteBase.pas
│ ├── mteChangeLogForm.dfm
│ ├── mteChangeLogForm.pas
│ ├── mteHelpers.pas
│ ├── mteLogger.pas
│ ├── mteLogging.pas
│ ├── mtePluginSelectionForm.dfm
│ ├── mtePluginSelectionForm.pas
│ ├── mteProgressForm.dfm
│ ├── mteProgressForm.pas
│ ├── mteTaskHandler.pas
│ └── mteTracker.pas
├── superobject/
│ └── superobject.pas
├── xedit/
│ ├── lz4/
│ │ ├── lz4.pas
│ │ ├── lz4Common.pas
│ │ ├── lz4HC.pas
│ │ ├── lz4frame.pas
│ │ ├── lz4frame_static.pas
│ │ ├── lz4io.pas
│ │ └── xxHash.pas
│ ├── wbBSA.pas
│ ├── wbDefines.inc
│ ├── wbDefinitionsFNV.pas
│ ├── wbDefinitionsFO3.pas
│ ├── wbDefinitionsFO4.pas
│ ├── wbDefinitionsTES3.pas
│ ├── wbDefinitionsTES4.pas
│ ├── wbDefinitionsTES5.pas
│ ├── wbHelpers.pas
│ ├── wbImplementation.pas
│ ├── wbInit.pas
│ ├── wbInterface.pas
│ ├── wbLocalization.pas
│ ├── wbSort.pas
│ ├── wbStreams.pas
│ └── zlib/
│ ├── ZLibEx.inc
│ ├── ZLibExApi.pas
│ ├── win32/
│ │ ├── adler32.obj
│ │ ├── compress.obj
│ │ ├── crc32.obj
│ │ ├── deflate.obj
│ │ ├── infback.obj
│ │ ├── inffast.obj
│ │ ├── inflate.obj
│ │ ├── inftrees.obj
│ │ └── trees.obj
│ ├── win64/
│ │ ├── adler32.obj
│ │ ├── compress.obj
│ │ ├── crc32.obj
│ │ ├── deflate.obj
│ │ ├── infback.obj
│ │ ├── inffast.obj
│ │ ├── inflate.obj
│ │ ├── inftrees.obj
│ │ └── trees.obj
│ └── zlibex.pas
└── zeosdbo/
├── doc/
│ └── html/
│ ├── bugreporting.html
│ ├── buildingtests.html
│ ├── changes.html
│ ├── ede.css
│ ├── installation.html
│ ├── knownbugs.html
│ ├── license.html
│ ├── overview.html
│ ├── parameters.html
│ └── readme.html
├── packages/
│ └── DelphiXE/
│ ├── ZComponent.dpk
│ ├── ZComponent.dproj
│ ├── ZComponent.res
│ ├── ZComponentDesign.dpk
│ ├── ZComponentDesign.dproj
│ ├── ZComponentDesign.res
│ ├── ZCore.dpk
│ ├── ZCore.dproj
│ ├── ZCore.res
│ ├── ZDbc.dpk
│ ├── ZDbc.dproj
│ ├── ZDbc.res
│ ├── ZPackages.inc
│ ├── ZParseSql.dpk
│ ├── ZParseSql.dproj
│ ├── ZParseSql.res
│ ├── ZPlain.dpk
│ ├── ZPlain.dproj
│ ├── ZPlain.res
│ ├── ZeosDbo.groupproj
│ └── events good.txt
└── src/
├── Zeos.inc
├── ZeosLazarus.inc
├── component/
│ ├── ZAbstractConnection.pas
│ ├── ZAbstractDataset.pas
│ ├── ZAbstractRODataset.pas
│ ├── ZAbstractTable.pas
│ ├── ZComponent.dcr
│ ├── ZComponent.inc
│ ├── ZComponentReg.lrs
│ ├── ZComponentReg.pas
│ ├── ZConnection.pas
│ ├── ZConnectionGroup.pas
│ ├── ZDataset.pas
│ ├── ZDatasetUtils.pas
│ ├── ZGroupedConnection.pas
│ ├── ZIBEventAlerter.pas
│ ├── ZPgEventAlerter.pas
│ ├── ZPropertyEditor.pas
│ ├── ZQuerySQLEditor.pas
│ ├── ZROSqlEditor.pas
│ ├── ZSequence.pas
│ ├── ZSqlMetadata.pas
│ ├── ZSqlMonitor.pas
│ ├── ZSqlProcessor.pas
│ ├── ZSqlStrings.pas
│ ├── ZSqlTestForm.pas
│ ├── ZSqlUpdate.pas
│ ├── ZStoredProcedure.pas
│ ├── ZStreamBlob.pas
│ ├── ZUpdateSqlEditor.dfm
│ ├── ZUpdateSqlEditor.lfm
│ ├── ZUpdateSqlEditor.lrs
│ └── ZUpdateSqlEditor.pas
├── core/
│ ├── ZClasses.pas
│ ├── ZCollections.pas
│ ├── ZCompatibility.pas
│ ├── ZCore.inc
│ ├── ZEncoding.pas
│ ├── ZExprParser.pas
│ ├── ZExprToken.pas
│ ├── ZExpression.pas
│ ├── ZFunctions.pas
│ ├── ZFunctionsConvert.pas
│ ├── ZFunctionsDateTime.pas
│ ├── ZFunctionsMath.pas
│ ├── ZFunctionsOther.pas
│ ├── ZFunctionsStrings.pas
│ ├── ZMatchPattern.pas
│ ├── ZMessages.pas
│ ├── ZSysUtils.pas
│ ├── ZTokenizer.pas
│ ├── ZURL.pas
│ ├── ZVariables.pas
│ └── ZVariant.pas
├── dbc/
│ ├── ZDbc.inc
│ ├── ZDbcASA.pas
│ ├── ZDbcASAMetadata.pas
│ ├── ZDbcASAResultSet.pas
│ ├── ZDbcASAStatement.pas
│ ├── ZDbcASAUtils.pas
│ ├── ZDbcAdo.pas
│ ├── ZDbcAdoMetadata.pas
│ ├── ZDbcAdoResultSet.pas
│ ├── ZDbcAdoStatement.pas
│ ├── ZDbcAdoUtils.pas
│ ├── ZDbcCache.pas
│ ├── ZDbcCachedResultSet.pas
│ ├── ZDbcConnection.pas
│ ├── ZDbcDbLib.pas
│ ├── ZDbcDbLibMetadata.pas
│ ├── ZDbcDbLibResultSet.pas
│ ├── ZDbcDbLibStatement.pas
│ ├── ZDbcDbLibUtils.pas
│ ├── ZDbcGenericResolver.pas
│ ├── ZDbcInterbase6.pas
│ ├── ZDbcInterbase6Metadata.pas
│ ├── ZDbcInterbase6ResultSet.pas
│ ├── ZDbcInterbase6Statement.pas
│ ├── ZDbcInterbase6Utils.pas
│ ├── ZDbcIntfs.pas
│ ├── ZDbcLogging.pas
│ ├── ZDbcMetadata.pas
│ ├── ZDbcMySql.pas
│ ├── ZDbcMySqlMetadata.pas
│ ├── ZDbcMySqlResultSet.pas
│ ├── ZDbcMySqlStatement.pas
│ ├── ZDbcMySqlUtils.pas
│ ├── ZDbcOracle.pas
│ ├── ZDbcOracleMetadata.pas
│ ├── ZDbcOracleResultSet.pas
│ ├── ZDbcOracleStatement.pas
│ ├── ZDbcOracleUtils.pas
│ ├── ZDbcPooled.pas
│ ├── ZDbcPostgreSql.pas
│ ├── ZDbcPostgreSqlMetadata.pas
│ ├── ZDbcPostgreSqlResultSet.pas
│ ├── ZDbcPostgreSqlStatement.pas
│ ├── ZDbcPostgreSqlUtils.pas
│ ├── ZDbcResultSet.pas
│ ├── ZDbcResultSetMetadata.pas
│ ├── ZDbcSqLite.pas
│ ├── ZDbcSqLiteMetadata.pas
│ ├── ZDbcSqLiteResultSet.pas
│ ├── ZDbcSqLiteStatement.pas
│ ├── ZDbcSqLiteUtils.pas
│ ├── ZDbcStatement.pas
│ └── ZDbcUtils.pas
├── parsesql/
│ ├── ZAdoToken.pas
│ ├── ZGenericSqlAnalyser.pas
│ ├── ZGenericSqlToken.pas
│ ├── ZInterbaseAnalyser.pas
│ ├── ZInterbaseToken.pas
│ ├── ZMySqlAnalyser.pas
│ ├── ZMySqlToken.pas
│ ├── ZOracleAnalyser.pas
│ ├── ZOracleToken.pas
│ ├── ZParseSql.inc
│ ├── ZPostgreSqlAnalyser.pas
│ ├── ZPostgreSqlToken.pas
│ ├── ZScriptParser.pas
│ ├── ZSelectSchema.pas
│ ├── ZSqLiteAnalyser.pas
│ ├── ZSqLiteToken.pas
│ ├── ZSybaseAnalyser.pas
│ └── ZSybaseToken.pas
├── plain/
│ ├── ZPlain.inc
│ ├── ZPlainASAConstants.pas
│ ├── ZPlainASADriver.pas
│ ├── ZPlainAdo.pas
│ ├── ZPlainAdoDriver.pas
│ ├── ZPlainDbLibConstants.pas
│ ├── ZPlainDbLibDriver.pas
│ ├── ZPlainDriver.pas
│ ├── ZPlainFirebirdDriver.pas
│ ├── ZPlainFirebirdInterbaseConstants.pas
│ ├── ZPlainLoader.pas
│ ├── ZPlainMySqlConstants.pas
│ ├── ZPlainMySqlDriver.pas
│ ├── ZPlainOracleConstants.pas
│ ├── ZPlainOracleDriver.pas
│ ├── ZPlainPostgreSqlDriver.pas
│ └── ZPlainSqLiteDriver.pas
├── repl.awk
├── repl.instructions
└── repl.txt
Copy disabled (too large)
Download .json
Condensed preview — 708 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (18,959K chars).
[
{
"path": ".gitignore",
"chars": 1495,
"preview": "# Uncomment these types if you want even more clean repository. But be careful.\n# It can make harm to an existing projec"
},
{
"path": "LICENSE.txt",
"chars": 25753,
"preview": " MOZILLA PUBLIC LICENSE\n Version 1.1\n\n "
},
{
"path": "README.md",
"chars": 1822,
"preview": "# smash\nA tool for performing automatic conflict resolution between multiple Bethesda Plugin Files for TES and Fallout g"
},
{
"path": "design/code snippets/GetMasterElement.pas",
"chars": 1896,
"preview": "{for j := 0 to ElementCount(ae) - 1 do begin\n ne := ebi(ae, j);\n if (SortKey(ne, false) = sk) then begin\n Result :="
},
{
"path": "design/code snippets/Mator Smash v0.9.pas",
"chars": 52170,
"preview": "{\n Mator Smash v0.9.6\n created by matortheeternal\n \n * DESCRIPTION *\n This script will make a patch similar to a ba"
},
{
"path": "design/code snippets/better build algorithm.pas",
"chars": 2956,
"preview": "procedure LoadElementData(var sl: TStringList; container: IwbContainerElementRef);\nvar\n innerContainer: IwbContainerEle"
},
{
"path": "design/notes/algorithm problems.txt",
"chars": 30,
"preview": "1. Elements with the same name"
},
{
"path": "design/notes/handling.txt",
"chars": 1041,
"preview": "Things to handle: ignoring deletions, treat as single entity, priority, linking\n\nIgnoring deletions:\nWhen applied to an "
},
{
"path": "design/notes/high level design.txt",
"chars": 2320,
"preview": "Smash\n\nQ: Do we want profiles?\nA: Yes, because a user may have multiple load orders or games they want to use smash with"
},
{
"path": "design/notes/linking explanation.txt",
"chars": 766,
"preview": "1. we have a set of plugins\n2. each plugin has a smash setting\n3. each smash setting has a definition for certain record"
},
{
"path": "design/notes/todos 1024.txt",
"chars": 96,
"preview": "1. Plugin recommendations \"dictionary\"\n2. Plugin information form (and on main form?)\n3. Backend"
},
{
"path": "frontend/MatorSmash.dpr",
"chars": 5122,
"preview": "{*******************************************************************************\n\n The contents of this file are su"
},
{
"path": "frontend/MatorSmash.dproj",
"chars": 10685,
"preview": "\t<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n\t\t<PropertyGroup>\n\t\t\t<ProjectGuid>{12317C9C-736E"
},
{
"path": "frontend/MatorSmash.mes",
"chars": 7207,
"preview": "[GeneralSettings]\nMesVersion=4\nHandleExceptions=0\nLinkInCode=1\nAppendMapFileToBinary=1\nNoOwnMadExceptSettings=0\nCheckFil"
},
{
"path": "frontend/ModelSupport_MatorSmash/MatorSmash/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"b4zfh5af0zf_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"ea9vm1284dq_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msEditForm/default.txvpck",
"chars": 269,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"njkyjunm3h_v\">\n <property name=\"$defaultD"
},
{
"path": "frontend/ModelSupport_MatorSmash/msFrontend/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"n0j337jkpef_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msOptionsForm/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"z6ar60bu6om_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msProfileForm/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"y0bo0tytf3p_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msProfilePanel/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"ac7klwk840k_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msSmashForm/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"d40chv15btm_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msSplashForm/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"xigiykmxj3j_v\">\n <property name=\"$default"
},
{
"path": "frontend/ModelSupport_MatorSmash/msThreads/default.txvpck",
"chars": 270,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<nodeSet version=\"1.0\">\n <view uin=\"y6gq3u7hleh_v\">\n <property name=\"$default"
},
{
"path": "frontend/lang/english.lang",
"chars": 6561,
"preview": "{ TSmashForm }\n{ ## QuickBar ## }\nmsMain_QuickButton_Hint=Quick patch|Apply Smash.All to loaded plugins and #13#10genera"
},
{
"path": "frontend/msAlgorithm.pas",
"chars": 20262,
"preview": "unit msAlgorithm;\n\ninterface\n\nuses\n SysUtils, Classes,\n // superobject\n superobject,\n // mte units\n mteHelpers, mte"
},
{
"path": "frontend/msChoicePanel.pas",
"chars": 4042,
"preview": "unit msChoicePanel;\n\ninterface\n\nuses\n SysUtils, Classes, Controls, Dialogs, Graphics, Buttons, StdCtrls, ExtCtrls,\n Im"
},
{
"path": "frontend/msConfiguration.pas",
"chars": 9552,
"preview": "unit msConfiguration;\n\ninterface\n\nuses\n Classes, wbInterface,\n // mte units\n mteHelpers, RttiIni;\n\ntype\n TGameMode ="
},
{
"path": "frontend/msConflict.pas",
"chars": 30371,
"preview": "unit msConflict;\n\ninterface\n\nuses\n Classes, SysUtils,\n // mte units\n mteBase,\n // ms units\n msCore,\n // xEdit unit"
},
{
"path": "frontend/msConflictForm.dfm",
"chars": 33148,
"preview": "object ConflictForm: TConflictForm\n Left = 0\n Top = 0\n Caption = 'Combine smash settings'\n ClientHeight = 377\n Clie"
},
{
"path": "frontend/msConflictForm.pas",
"chars": 6424,
"preview": "unit msConflictForm;\n\ninterface\n\nuses\n Windows, Types, Messages, SysUtils, Variants, Classes, Graphics, Controls,\n For"
},
{
"path": "frontend/msCore.pas",
"chars": 53607,
"preview": "unit msCore;\n\ninterface\n\nuses\n Classes, Menus, ComCtrls, RegularExpressions,\n // third party libraries\n superobject,\n"
},
{
"path": "frontend/msEditForm.dfm",
"chars": 1809,
"preview": "object EditForm: TEditForm\n Left = 0\n Top = 0\n ActiveControl = edName\n Caption = 'Edit patch'\n ClientHeight = 151\n "
},
{
"path": "frontend/msEditForm.pas",
"chars": 4466,
"preview": "unit msEditForm;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n Dialogs"
},
{
"path": "frontend/msLoader.pas",
"chars": 18724,
"preview": "unit msLoader;\n\ninterface\n\nuses\n Classes,\n // mte units\n mteHelpers, mteBase,\n // mp units\n msConfiguration;\n\n { I"
},
{
"path": "frontend/msOptionsForm.dfm",
"chars": 22958,
"preview": "object OptionsForm: TOptionsForm\n Left = 0\n Top = 0\n Caption = 'Settings'\n ClientHeight = 447\n ClientWidth = 584\n "
},
{
"path": "frontend/msOptionsForm.pas",
"chars": 7542,
"preview": "unit msOptionsForm;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n Dial"
},
{
"path": "frontend/msPluginSelectionForm.dfm",
"chars": 2041,
"preview": "object MiniPluginSelectionForm: TMiniPluginSelectionForm\n Left = 0\n Top = 0\n Caption = 'Plugin selection'\n ClientHei"
},
{
"path": "frontend/msPluginSelectionForm.pas",
"chars": 2853,
"preview": "unit msPluginSelectionForm;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms"
},
{
"path": "frontend/msPriorityForm.dfm",
"chars": 1385,
"preview": "object PriorityForm: TPriorityForm\n Left = 0\n Top = 0\n Caption = 'Change node priority'\n ClientHeight = 134\n Client"
},
{
"path": "frontend/msPriorityForm.pas",
"chars": 641,
"preview": "unit msPriorityForm;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n Dia"
},
{
"path": "frontend/msProfileForm.dfm",
"chars": 701590,
"preview": "object ProfileForm: TProfileForm\n Left = 0\n Top = 0\n Caption = 'Select Profile'\n ClientHeight = 467\n ClientWidth = "
},
{
"path": "frontend/msProfileForm.pas",
"chars": 8891,
"preview": "unit msProfileForm;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Classes, Controls, Forms, StdCtrls, Graphics,\n ImgL"
},
{
"path": "frontend/msProfilePanel.pas",
"chars": 8343,
"preview": "unit msProfilePanel;\n\ninterface\n\nuses\n SysUtils, Classes, Controls, Dialogs, Graphics, Buttons, StdCtrls, ExtCtrls,\n I"
},
{
"path": "frontend/msSettingsManager.dfm",
"chars": 49572,
"preview": "object SettingsManager: TSettingsManager\n Left = 0\n Top = 0\n Caption = 'Settings Manager'\n ClientHeight = 582\n Clie"
},
{
"path": "frontend/msSettingsManager.pas",
"chars": 39642,
"preview": "unit msSettingsManager;\n\ninterface\n\nuses\n Windows, Types, Messages, SysUtils, Variants, Classes, Graphics, Controls,\n "
},
{
"path": "frontend/msSmash.pas",
"chars": 16267,
"preview": "unit msSmash;\n\ninterface\n\nuses\n Windows, SysUtils, Classes, ShellAPI, Controls, Dialogs,\n // superobject\n superobject"
},
{
"path": "frontend/msSmashForm.dfm",
"chars": 166676,
"preview": "object SmashForm: TSmashForm\n Left = 0\n Top = 0\n Caption = 'Mator Smash'\n ClientHeight = 682\n ClientWidth = 1264\n "
},
{
"path": "frontend/msSmashForm.pas",
"chars": 71736,
"preview": "unit msSmashForm;\n\ninterface\n\nuses\n // delphi units\n Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, "
},
{
"path": "frontend/msSplashForm.dfm",
"chars": 995811,
"preview": "object SplashForm: TSplashForm\n Left = 0\n Top = 0\n BorderIcons = []\n BorderStyle = bsSingle\n Caption = 'Mator Smash"
},
{
"path": "frontend/msSplashForm.pas",
"chars": 976,
"preview": "unit msSplashForm;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n Dialo"
},
{
"path": "frontend/msTagHelper.dfm",
"chars": 1198,
"preview": "object TagHelper: TTagHelper\n Left = 0\n Top = 0\n Caption = 'Tag Helper'\n ClientHeight = 412\n ClientWidth = 334\n Co"
},
{
"path": "frontend/msTagHelper.pas",
"chars": 1672,
"preview": "unit msTagHelper;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n Dialog"
},
{
"path": "frontend/msTagManager.dfm",
"chars": 2567,
"preview": "object TagManager: TTagManager\n Left = 0\n Top = 0\n Caption = 'Manage Tags'\n ClientHeight = 312\n ClientWidth = 434\n "
},
{
"path": "frontend/msTagManager.pas",
"chars": 4272,
"preview": "unit msTagManager;\n\ninterface\n\nuses\n Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,\n Dialo"
},
{
"path": "frontend/msThreads.pas",
"chars": 7388,
"preview": "unit msThreads;\n\ninterface\n\nuses\n Classes, SysUtils, StrUtils, shlObj, Dialogs, ComCtrls,\n Windows, MMSystem,\n // sup"
},
{
"path": "frontend/settings/Fallout3/Smash.All.json",
"chars": 183852,
"preview": "{\"records\":\"ACHR,ACTI,ADDN,ALCH,AMMO,ANIO,ARMA,ARMO,ASPC,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLMT,COBJ,CONT,CPTH,CREA,CSTY,DEB"
},
{
"path": "frontend/settings/Fallout4/Smash.All.json",
"chars": 511820,
"preview": "{\"records\":\"ACHR,ACTI,ADDN,AECH,ALCH,AMDL,AMMO,ANIO,AORU,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BNDS,BOOK,BPTD,CAMS,CELL,CLAS,CLF"
},
{
"path": "frontend/settings/FalloutNV/Smash.All.json",
"chars": 208381,
"preview": "{\"records\":\"ACHR,ACTI,ADDN,ALCH,ALOC,AMEF,AMMO,ANIO,ARMA,ARMO,ASPC,AVIF,BOOK,BPTD,CAMS,CCRD,CDCK,CELL,CHAL,CHIP,CLAS,CLM"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.ACBS.json",
"chars": 4962,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.ACBS tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC ACBS configu"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.AIData.json",
"chars": 4967,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.AIData tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI data.\","
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.AIPackages.json",
"chars": 4900,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.AIPackages tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI pac"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.Animations.json",
"chars": 4920,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Animations tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature o"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.CombatStyle.json",
"chars": 4875,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.CombatStyle tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC comba"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.DeathItem.json",
"chars": 4881,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.DeathItem tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.Skeleton.json",
"chars": 4921,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Skeleton from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC "
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.Spells.json",
"chars": 4898,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Spells tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies creature or NPC"
},
{
"path": "frontend/settings/Oblivion/Bash.Actors.Stats.json",
"chars": 5161,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Actors.Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC"
},
{
"path": "frontend/settings/Oblivion/Bash.Body-F.json",
"chars": 2903,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body mesh\\/texture "
},
{
"path": "frontend/settings/Oblivion/Bash.Body-M.json",
"chars": 2901,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body mesh\\/texture de"
},
{
"path": "frontend/settings/Oblivion/Bash.Body-Size-F.json",
"chars": 2866,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-Size-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body weight\\/h"
},
{
"path": "frontend/settings/Oblivion/Bash.Body-Size-M.json",
"chars": 2864,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-Size-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body weight\\/hei"
},
{
"path": "frontend/settings/Oblivion/Bash.C.Climate.json",
"chars": 1235,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Climate tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell climates.\",\"tree\":"
},
{
"path": "frontend/settings/Oblivion/Bash.C.Light.json",
"chars": 1346,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Light tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell lighting or fog.\",\"t"
},
{
"path": "frontend/settings/Oblivion/Bash.C.Music.json",
"chars": 1233,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Music tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell music type.\",\"tree\":"
},
{
"path": "frontend/settings/Oblivion/Bash.C.Name.json",
"chars": 1226,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Name tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell names.\",\"tree\":{\"reco"
},
{
"path": "frontend/settings/Oblivion/Bash.C.Owner.json",
"chars": 1256,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Owner tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell ownership.\",\"tree\":{"
},
{
"path": "frontend/settings/Oblivion/Bash.C.RecordFlags.json",
"chars": 1263,
"preview": "{\"records\":\"CELL\",\"description\":\"C.RecordFlags tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies the off-limits or d"
},
{
"path": "frontend/settings/Oblivion/Bash.C.Water.json",
"chars": 1248,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Water tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell water type or level."
},
{
"path": "frontend/settings/Oblivion/Bash.Creatures.Blood.json",
"chars": 2401,
"preview": "{\"records\":\"CREA\",\"description\":\"Creatures.Blood tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies the creature bloo"
},
{
"path": "frontend/settings/Oblivion/Bash.Eyes.json",
"chars": 2817,
"preview": "{\"records\":\"RACE\",\"description\":\"Eyes tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds eyes to races.\",\"tree\":{\"records"
},
{
"path": "frontend/settings/Oblivion/Bash.Factions.json",
"chars": 4922,
"preview": "{\"records\":\"NPC_,CREA\",\"description\":\"Factions tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies creature or NPC fac"
},
{
"path": "frontend/settings/Oblivion/Bash.Graphics.json",
"chars": 27764,
"preview": "{\"records\":\"ALCH,AMMO,APPA,ARMO,BOOK,BSGN,CLAS,CLOT,CREA,DOOR,EFSH,FLOR,FURN,GRAS,INGR,KEYM,LIGH,LSCR,LTEX,MGEF,MISC,REG"
},
{
"path": "frontend/settings/Oblivion/Bash.Hair.json",
"chars": 2818,
"preview": "{\"records\":\"RACE\",\"description\":\"Hair tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds hairs to races.\",\"tree\":{\"record"
},
{
"path": "frontend/settings/Oblivion/Bash.Invent.json",
"chars": 5425,
"preview": "{\"records\":\"CREA,NPC_,CONT\",\"description\":\"Invent tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes inventories.\",\"tr"
},
{
"path": "frontend/settings/Oblivion/Bash.Lev.json",
"chars": 1305,
"preview": "{\"records\":\"LVLC,LVSP,LVLI\",\"description\":\"Base setting for Wrye Bash's leveled list handling.\\r\\n\\r\\nWhen used, leveled"
},
{
"path": "frontend/settings/Oblivion/Bash.NPC.Class.json",
"chars": 2674,
"preview": "{\"records\":\"NPC_\",\"description\":\"NPC.Class tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes the classes of NPCs.\",\"t"
},
{
"path": "frontend/settings/Oblivion/Bash.NPC.Race.json",
"chars": 2663,
"preview": "{\"records\":\"NPC_\",\"description\":\"NPC.Race tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC races.\",\"tree\":{\"rec"
},
{
"path": "frontend/settings/Oblivion/Bash.Names.json",
"chars": 39165,
"preview": "{\"records\":\"ALCH,AMMO,APPA,ARMO,BOOK,BSGN,CELL,CLAS,CLOT,CONT,CREA,DIAL,DOOR,ENCH,EYES,FACT,FLOR,FURN,HAIR,INGR,KEYM,LIG"
},
{
"path": "frontend/settings/Oblivion/Bash.Npc.EyesOnly.json",
"chars": 2681,
"preview": "{\"records\":\"NPC_\",\"description\":\"Npc.HairOnly tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies NPC eyes.\",\"tree\":{\"r"
},
{
"path": "frontend/settings/Oblivion/Bash.Npc.HairOnly.json",
"chars": 2669,
"preview": "{\"records\":\"NPC_\",\"description\":\"Npc.HairOnly tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies NPC hair.\",\"tree\":{\"r"
},
{
"path": "frontend/settings/Oblivion/Bash.NpcFaces.json",
"chars": 2753,
"preview": "{\"records\":\"NPC_\",\"description\":\"NpcFaces tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces.\",\"tree\":{\"rec"
},
{
"path": "frontend/settings/Oblivion/Bash.NpcFacesForceFullImport.json",
"chars": 3130,
"preview": "{\"records\":\"NPC_\",\"description\":\"NpcFacesForceFullImport tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces"
},
{
"path": "frontend/settings/Oblivion/Bash.R.AddSpells.json",
"chars": 2924,
"preview": "{\"records\":\"RACE\",\"description\":\"R.AddSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds spells to racial spell li"
},
{
"path": "frontend/settings/Oblivion/Bash.R.Attributes-F.json",
"chars": 2904,
"preview": "{\"records\":\"RACE\",\"description\":\"R.Attributes-F tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies racial attributes f"
},
{
"path": "frontend/settings/Oblivion/Bash.R.Attributes-M.json",
"chars": 2902,
"preview": "{\"records\":\"RACE\",\"description\":\"R.Attributes-M tag from Wrye Bash.\\r\\n\\r\\nUse when the mod modifies racial attributes f"
},
{
"path": "frontend/settings/Oblivion/Bash.R.ChangeSpells.json",
"chars": 2953,
"preview": "{\"records\":\"RACE\",\"description\":\"R.ChangeSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies racial spell list("
},
{
"path": "frontend/settings/Oblivion/Bash.R.Description.json",
"chars": 2837,
"preview": "{\"records\":\"RACE\",\"description\":\"R.Description tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race descriptions.\""
},
{
"path": "frontend/settings/Oblivion/Bash.Relations.json",
"chars": 668,
"preview": "{\"records\":\"FACT\",\"description\":\"Relations tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies faction relationships.\""
},
{
"path": "frontend/settings/Oblivion/Bash.Scripts.json",
"chars": 26956,
"preview": "{\"records\":\"ALCH,APPA,ARMO,BOOK,CLOT,CONT,CREA,DOOR,FLOR,FURN,INGR,KEYM,LIGH,LVLC,MISC,NPC_,QUST,SGST,SLGM,WEAP,ACTI\",\"d"
},
{
"path": "frontend/settings/Oblivion/Bash.Sound.json",
"chars": 7490,
"preview": "{\"records\":\"CONT,CREA,DOOR,LIGH,MGEF,WTHR,ACTI\",\"description\":\"Sound tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod replac"
},
{
"path": "frontend/settings/Oblivion/Bash.SpellStats.json",
"chars": 2382,
"preview": "{\"records\":\"SPEL\",\"description\":\"SpellStats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies spell stats.\",\"tree\":{"
},
{
"path": "frontend/settings/Oblivion/Bash.Stats.json",
"chars": 13166,
"preview": "{\"records\":\"ALCH,APPA,ARMO,BOOK,CLOT,INGR,KEYM,LIGH,MISC,SGST,WEAP,AMMO\",\"description\":\"Stats tag from Wrye Bash.\\r\\n\\r\\"
},
{
"path": "frontend/settings/Oblivion/Bash.Voice-F.json",
"chars": 2838,
"preview": "{\"records\":\"RACE\",\"description\":\"Voice-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female voice definitions."
},
{
"path": "frontend/settings/Oblivion/Bash.Voice-M.json",
"chars": 2836,
"preview": "{\"records\":\"RACE\",\"description\":\"Voice-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male voice definitions.\","
},
{
"path": "frontend/settings/Oblivion/Smash.All.json",
"chars": 82667,
"preview": "{\"records\":\"ACRE,ACTI,ALCH,AMMO,ANIO,APPA,ARMO,BOOK,BSGN,CELL,CLAS,CLMT,CLOT,CONT,CREA,CSTY,DIAL,DOOR,EFSH,ENCH,EYES,FAC"
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.ACBS.json",
"chars": 6785,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.ACBS tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC ACBS configuratio"
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.AIData.json",
"chars": 6784,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.AIData tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI data.\",\"tree"
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.AIPackages.json",
"chars": 6741,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.AIPackages tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC AI packages"
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.AIPackagesMerge.json",
"chars": 6914,
"preview": "{\"records\":\"NPC_\",\"description\":\"An alternative to the Actors.AIPackagesForceAdd tag from Wrye Bash.\\r\\n\\r\\nMator Smash "
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.CombatStyle.json",
"chars": 6722,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.CombatStyle tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC combat sty"
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.DeathItem.json",
"chars": 6716,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.DeathItem tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC death items."
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.Spells.json",
"chars": 6728,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.Spells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC spell lists.\",\""
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.SpellsMerge.json",
"chars": 6900,
"preview": "{\"records\":\"NPC_\",\"description\":\"An alternative to the Actors.SpellsForceAdd tag from Wrye Bash.\\r\\n\\r\\nMator Smash cann"
},
{
"path": "frontend/settings/Skyrim/Bash.Actors.Stats.json",
"chars": 6978,
"preview": "{\"records\":\"NPC_\",\"description\":\"Actors.Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC stats.\",\"tree\":{"
},
{
"path": "frontend/settings/Skyrim/Bash.All.json",
"chars": 133723,
"preview": "{\"records\":\"ACTI,ALCH,AMMO,APPA,ARMA,ARMO,ARTO,ASPC,AVIF,BOOK,CELL,CLAS,CONT,DEBR,DIAL,DOOR,EFSH,ENCH,EXPL,FACT,FLOR,FUR"
},
{
"path": "frontend/settings/Skyrim/Bash.Body-F.json",
"chars": 6171,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body mesh\\/texture "
},
{
"path": "frontend/settings/Skyrim/Bash.Body-M.json",
"chars": 6169,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body mesh\\/texture de"
},
{
"path": "frontend/settings/Skyrim/Bash.Body-Size-F.json",
"chars": 6164,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-Size-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female body weight\\/h"
},
{
"path": "frontend/settings/Skyrim/Bash.Body-Size-M.json",
"chars": 6162,
"preview": "{\"records\":\"RACE\",\"description\":\"Body-Size-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male body weight\\/hei"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Acoustic.json",
"chars": 3244,
"preview": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\""
},
{
"path": "frontend/settings/Skyrim/Bash.C.Climate.json",
"chars": 3321,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Climate tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell climates.\",\"tree\":"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Encounter.json",
"chars": 3245,
"preview": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\""
},
{
"path": "frontend/settings/Skyrim/Bash.C.ImageSpace.json",
"chars": 3258,
"preview": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"d\":1,\"c\":[{\"t\":6,\"n\":\"Record Heade"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Light.json",
"chars": 3708,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Light tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell lighting or fog.\",\"t"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Location.json",
"chars": 3244,
"preview": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\""
},
{
"path": "frontend/settings/Skyrim/Bash.C.Music.json",
"chars": 3319,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Music tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell music type.\",\"tree\":"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Name.json",
"chars": 3312,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Name tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell names.\",\"tree\":{\"reco"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Owner.json",
"chars": 3330,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Owner tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell ownership.\",\"tree\":{"
},
{
"path": "frontend/settings/Skyrim/Bash.C.RecordFlags.json",
"chars": 3355,
"preview": "{\"records\":\"CELL\",\"description\":\"C.RecordFlags tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies the off-limits or d"
},
{
"path": "frontend/settings/Skyrim/Bash.C.Regions.json",
"chars": 3249,
"preview": "{\"records\":\"CELL\",\"description\":\"\",\"tree\":{\"records\":[{\"t\":1,\"p\":1,\"n\":\"CELL - Cell\",\"c\":[{\"t\":6,\"n\":\"Record Header\",\"c\""
},
{
"path": "frontend/settings/Skyrim/Bash.C.Water.json",
"chars": 3334,
"preview": "{\"records\":\"CELL\",\"description\":\"C.Water tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies cell water type or level."
},
{
"path": "frontend/settings/Skyrim/Bash.Delev.json",
"chars": 2788,
"preview": "{\"records\":\"LVLI,LVSP,LVLN\",\"description\":\"Delev tag from Wrye Bash.\\r\\n\\r\\nRemoval of entries from the leveled list ent"
},
{
"path": "frontend/settings/Skyrim/Bash.Eyes.json",
"chars": 6108,
"preview": "{\"records\":\"RACE\",\"description\":\"Eyes tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds eyes to races.\",\"tree\":{\"records"
},
{
"path": "frontend/settings/Skyrim/Bash.Factions.json",
"chars": 6733,
"preview": "{\"records\":\"NPC_\",\"description\":\"Factions tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC factions.\",\"tree\":{\""
},
{
"path": "frontend/settings/Skyrim/Bash.Graphics.json",
"chars": 45855,
"preview": "{\"records\":\"ACTI,AMMO,APPA,ARMA,ARMO,ARTO,BOOK,DEBR,DOOR,EFSH,EXPL,FLOR,FURN,GRAS,INGR,LIGH,LSCR,MGEF,MISC,MSTT,PROJ,SCR"
},
{
"path": "frontend/settings/Skyrim/Bash.Hairs.json",
"chars": 6112,
"preview": "{\"records\":\"RACE\",\"description\":\"Hairs tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds hairs to races.\",\"tree\":{\"recor"
},
{
"path": "frontend/settings/Skyrim/Bash.Invent.json",
"chars": 8128,
"preview": "{\"records\":\"NPC_,CONT\",\"description\":\"Invent tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes inventories.\",\"tree\":{"
},
{
"path": "frontend/settings/Skyrim/Bash.Lev.json",
"chars": 2460,
"preview": "{\"records\":\"LVLI,LVSP,LVLN\",\"description\":\"Base setting for Wrye Bash's leveled list handling.\\r\\n\\r\\nWhen used, leveled"
},
{
"path": "frontend/settings/Skyrim/Bash.NPC.Class.json",
"chars": 6705,
"preview": "{\"records\":\"NPC_\",\"description\":\"NPC.Class tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod changes the classes of NPCs.\",\"t"
},
{
"path": "frontend/settings/Skyrim/Bash.NPC.Race.json",
"chars": 6694,
"preview": "{\"records\":\"NPC_\",\"description\":\"NPC.Race tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC races.\",\"tree\":{\"rec"
},
{
"path": "frontend/settings/Skyrim/Bash.Names.json",
"chars": 74981,
"preview": "{\"records\":\"ACTI,AMMO,ARMO,AVIF,BOOK,CLAS,CONT,DIAL,DOOR,ENCH,EXPL,FACT,FLOR,FURN,HAZD,HDPT,INGR,KEYM,LCTN,LIGH,MESG,MGE"
},
{
"path": "frontend/settings/Skyrim/Bash.NpcFaces.json",
"chars": 6934,
"preview": "{\"records\":\"NPC_\",\"description\":\"NpcFaces tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces.\",\"tree\":{\"rec"
},
{
"path": "frontend/settings/Skyrim/Bash.NpcFacesForceFullImport.json",
"chars": 7389,
"preview": "{\"records\":\"NPC_\",\"description\":\"NpcFacesForceFullImport tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies NPC faces"
},
{
"path": "frontend/settings/Skyrim/Bash.R.AddSpells.json",
"chars": 6216,
"preview": "{\"records\":\"RACE\",\"description\":\"R.AddSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod adds spells to racial spell li"
},
{
"path": "frontend/settings/Skyrim/Bash.R.ChangeSpells.json",
"chars": 6245,
"preview": "{\"records\":\"RACE\",\"description\":\"R.ChangeSpells tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies racial spell list("
},
{
"path": "frontend/settings/Skyrim/Bash.R.Description.json",
"chars": 6129,
"preview": "{\"records\":\"RACE\",\"description\":\"R.Description tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race descriptions.\""
},
{
"path": "frontend/settings/Skyrim/Bash.R.Head.json",
"chars": 6168,
"preview": "{\"records\":\"RACE\",\"description\":\"R.Head tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race heads.\",\"tree\":{\"reco"
},
{
"path": "frontend/settings/Skyrim/Bash.R.Skills.json",
"chars": 6510,
"preview": "{\"records\":\"RACE\",\"description\":\"R.Skills tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies race skill bonuses.\",\"tr"
},
{
"path": "frontend/settings/Skyrim/Bash.Relations.json",
"chars": 2166,
"preview": "{\"records\":\"FACT\",\"description\":\"Relations tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies faction relationships.\""
},
{
"path": "frontend/settings/Skyrim/Bash.Relev.json",
"chars": 2967,
"preview": "{\"records\":\"LVLI,LVSP,LVLN\",\"description\":\"Relev tag from Wrye Bash.\\r\\n\\r\\nRe-levelling of entries from the leveled lis"
},
{
"path": "frontend/settings/Skyrim/Bash.Scripts.json",
"chars": 55320,
"preview": "{\"records\":\"ACHR,ACTI,ARMO,BOOK,CONT,DOOR,FLOR,FURN,INFO,INGR,KEYM,LIGH,MGEF,MISC,NPC_,PACK,PERK,PHZD,QUST,REFR,SCEN,TRE"
},
{
"path": "frontend/settings/Skyrim/Bash.Sound.json",
"chars": 46726,
"preview": "{\"records\":\"ARMA,ARMO,ASPC,EXPL,IPCT,MGEF,MISC,MSTT,RACE,REVB,SLGM,SNCT,SNDR,SOPM,SOUN,WEAP,WTHR,ACTI\",\"description\":\"So"
},
{
"path": "frontend/settings/Skyrim/Bash.SpellStats.json",
"chars": 1366,
"preview": "{\"records\":\"SPEL\",\"description\":\"SpellStats tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies spell stats.\",\"tree\":{"
},
{
"path": "frontend/settings/Skyrim/Bash.Stats.json",
"chars": 17335,
"preview": "{\"records\":\"AMMO,APPA,ARMO,BOOK,INGR,KEYM,MISC,PROJ,WEAP,ALCH\",\"description\":\"Stats tag from Wrye Bash.\\r\\n\\r\\nUsed when"
},
{
"path": "frontend/settings/Skyrim/Bash.Voice-F.json",
"chars": 6142,
"preview": "{\"records\":\"RACE\",\"description\":\"Voice-F tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies female voice definitions."
},
{
"path": "frontend/settings/Skyrim/Bash.Voice-M.json",
"chars": 6140,
"preview": "{\"records\":\"RACE\",\"description\":\"Voice-M tag from Wrye Bash.\\r\\n\\r\\nUsed when the mod modifies male voice definitions.\","
},
{
"path": "frontend/settings/Skyrim/Skip.json",
"chars": 186,
"preview": "{\"records\":\"\",\"description\":\"Special setting. Any plugin with this setting will be excluded from patch creation.\",\"tree"
},
{
"path": "frontend/settings/Skyrim/Smash.All.json",
"chars": 346192,
"preview": "{\"records\":\"AACT,ACTI,ADDN,ALCH,AMMO,ANIO,APPA,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLDC,CLFM,CLMT,COB"
},
{
"path": "frontend/settings/Skyrim/Smash.ForceAll.json",
"chars": 346931,
"preview": "{\"records\":\"AACT,ACTI,ADDN,ALCH,AMMO,ANIO,APPA,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLDC,CLFM,CLMT,COB"
},
{
"path": "frontend/settings/Skyrim/Smash.OverrideAll.json",
"chars": 346098,
"preview": "{\"records\":\"AACT,ACTI,ADDN,ALCH,AMMO,ANIO,APPA,ARMA,ARMO,ARTO,ASPC,ASTP,AVIF,BOOK,BPTD,CAMS,CELL,CLAS,CLDC,CLFM,CLMT,COB"
},
{
"path": "frontend/smash.rc",
"chars": 33,
"preview": "SMASH WAV \".\\Resources\\smash.wav\""
},
{
"path": "lib/Imaging/Imaging.pas",
"chars": 141369,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingBitmap.pas",
"chars": 28013,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingCanvases.pas",
"chars": 71642,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder\n http://imaginglib.sourceforge.net\n\n The contents of this file are used "
},
{
"path": "lib/Imaging/ImagingClasses.pas",
"chars": 35383,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingColors.pas",
"chars": 7847,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingComponents.pas",
"chars": 42517,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingDds.pas",
"chars": 43601,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder\n http://imaginglib.sourceforge.net\n\n The contents of this file are used "
},
{
"path": "lib/Imaging/ImagingFormats.pas",
"chars": 138870,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingIO.pas",
"chars": 18747,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingNetworkGraphics.pas",
"chars": 85962,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingOptions.inc",
"chars": 6694,
"preview": "{\n User Options\n Following defines and options can be changed by user.\n}\n\n{ Source options }\n\n{$DEFINE USE_INLINE} "
},
{
"path": "lib/Imaging/ImagingTarga.pas",
"chars": 18511,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingTypes.pas",
"chars": 24297,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ImagingUtility.pas",
"chars": 47109,
"preview": "{\n Vampyre Imaging Library\n by Marek Mauder \n http://imaginglib.sourceforge.net\n\n The contents of this file are used"
},
{
"path": "lib/Imaging/ZLib/dzlib.pas",
"chars": 15784,
"preview": "{*******************************************************}\n{ }\n{ "
},
{
"path": "lib/Imaging/ZLib/imadler.pas",
"chars": 2459,
"preview": "Unit imadler;\n\n{\n adler32.c -- compute the Adler-32 checksum of a data stream\n Copyright (C) 1995-1998 Mark Adler\n\n P"
},
{
"path": "lib/Imaging/ZLib/iminfblock.pas",
"chars": 28159,
"preview": "Unit iminfblock;\n\n{ infblock.h and\n infblock.c -- interpret and process block types to last block\n Copyright (C) 1995-"
},
{
"path": "lib/Imaging/ZLib/iminfcodes.pas",
"chars": 15099,
"preview": "Unit iminfcodes;\n\n{ infcodes.c -- process literals and length/distance pairs\n Copyright (C) 1995-1998 Mark Adler\n\n Pas"
},
{
"path": "lib/Imaging/ZLib/iminffast.pas",
"chars": 8894,
"preview": "Unit iminffast;\n\n{\n inffast.h and\n inffast.c -- process literals and length/distance pairs fast\n Copyright (C) 1995-1"
},
{
"path": "lib/Imaging/ZLib/iminftrees.pas",
"chars": 28350,
"preview": "Unit iminftrees;\n\n{ inftrees.h -- header to use inftrees.c\n inftrees.c -- generate Huffman trees for efficient decoding"
},
{
"path": "lib/Imaging/ZLib/iminfutil.pas",
"chars": 4869,
"preview": "Unit iminfutil;\n\n{ types and macros common to blocks and codes\n Copyright (C) 1995-1998 Mark Adler\n\n WARNING: this fi"
},
{
"path": "lib/Imaging/ZLib/impaszlib.pas",
"chars": 17799,
"preview": "Unit impaszlib;\n\n\n{ Original:\n zlib.h -- interface of the 'zlib' general purpose compression library\n version 1.1.0, "
},
{
"path": "lib/Imaging/ZLib/imtrees.pas",
"chars": 77177,
"preview": "Unit imtrees;\n\n{$T-}\n{$define ORG_DEBUG}\n{\n trees.c -- output deflated data using Huffman coding\n Copyright (C) 1995-1"
},
{
"path": "lib/Imaging/ZLib/imzconf.inc",
"chars": 649,
"preview": "{ -------------------------------------------------------------------- }\n\n{$DEFINE MAX_MATCH_IS_258}\n\n{ Compile with -DM"
},
{
"path": "lib/Imaging/ZLib/imzdeflate.pas",
"chars": 72963,
"preview": "Unit imzdeflate;\n\n{ Orginal: deflate.h -- internal compression state\n deflate.c -- compress data using the def"
},
{
"path": "lib/Imaging/ZLib/imzinflate.pas",
"chars": 22250,
"preview": "Unit imzinflate;\n\n{ inflate.c -- zlib interface to inflate modules\n Copyright (C) 1995-1998 Mark Adler\n\n Pascal tra"
},
{
"path": "lib/Imaging/ZLib/imzutil.pas",
"chars": 3892,
"preview": "Unit imzutil;\n\n{\n Copyright (C) 1998 by Jacques Nomssi Nzali\n For conditions of distribution and use, see copyright no"
},
{
"path": "lib/Imaging/ZLib/readme.txt",
"chars": 5205,
"preview": "_____________________________________________________________________________\n\nPASZLIB 1.0 "
},
{
"path": "lib/abbrevia/MPL-1_1.txt",
"chars": 25755,
"preview": " MOZILLA PUBLIC LICENSE\n Version 1.1\n\n "
},
{
"path": "lib/abbrevia/Readme.html",
"chars": 11306,
"preview": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n<html lang=\"en-us\">\n<head>\n <title>Abbrevia v5.0</title"
},
{
"path": "lib/abbrevia/WavPack License.txt",
"chars": 1558,
"preview": " Copyright (c) 1998 - 2009 Conifer Software\n All rights reserved.\n\nRedistribution"
},
{
"path": "lib/abbrevia/examples/Delphi/Abbrexam.dpr",
"chars": 1430,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
},
{
"path": "lib/abbrevia/examples/Delphi/BaseDlgu.pas",
"chars": 1583,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
},
{
"path": "lib/abbrevia/examples/Delphi/CabExt.dpr",
"chars": 1329,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
},
{
"path": "lib/abbrevia/examples/Delphi/CabExt1.pas",
"chars": 3060,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
},
{
"path": "lib/abbrevia/examples/Delphi/CabFind.dpr",
"chars": 1292,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
},
{
"path": "lib/abbrevia/examples/Delphi/CabFind1.pas",
"chars": 3501,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
},
{
"path": "lib/abbrevia/examples/Delphi/CabView.dpr",
"chars": 1016,
"preview": "(* ***** BEGIN LICENSE BLOCK *****\n * Version: MPL 1.1\n *\n * The contents of this file are subject to the Mozilla Public"
}
]
// ... and 508 more files (download for full content)
About this extraction
This page contains the full source code of the matortheeternal/smash GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 708 files (17.0 MB), approximately 4.5M tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.