{      Sheson - Dynamic Distant Objects LOD - DynDOLOD Worlds beta 0.55.00

This scripts updates DynDOLOD.esp for in-game use and TES5LODGen.

1) Do LODGen for trees first
2) Run DynDOLOD Worlds.pas
3) Select world
3) Point to data folder that has all the lod meshes, default (meshes\lod) and custom (meshes\dyndolod)
4) set all other options as desired and start process by clicking OK
5) get coffee or plant a tree
6) Close TES5Edit and let it save changed "DynDOLOD.esp"

Option window dimensions can be changed in this script file, just scroll down a bit.

LODGen and DynDOLOD require meshes used in LOD to exist in the Data folder
to work properly, otherwise there will be missing distant objects in game.

Use and modify this as you wish, please give credit if you use anything from DynDOLOD, models, code etc.
If you want to update or create any assets for this, I will happily add them to the package and give credit.

Credit to TES5Edit Team http://www.nexusmods.com/skyrim/mods/25859/
Credit to Ehamloptiran and Zilav for LODGen, part of TES5Edit
Credit to Bethesda for the game and models/textures

=======================================================================================

Sheson - Holy Cow I fixed Skyrim

=======================================================================================

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 


  
}

unit userscript;

const
  // Options window width >= 835
  WindowWidth = 835;
  // Options window height >= 550
  WindowHeight = 550;

  // max dimensions of a texture atlas, if needed it will create additional atlas files
  // to avoid mipmap artifacts it should be one of 128, 256, 512, 1024, 2048, 4096, 8192
  iAtlasMaxWidth = 4096;
  iAtlasMaxHeight = 4096;
  // max size of source lod texture to be included in atlas
  iAtlasTextureSize = 512;

//============================================================================================//
// Nothing to change beyond this point unless you are a machohist or a guru, refer to the ini //
//============================================================================================//

uses 'DynDOLOD\lib\lodgenalt';
uses 'DynDOLOD\lib\treelodpatcheralt';
uses 'DynDOLOD\lib\optionsform';
uses 'DynDOLOD\lib\prepare';
uses 'DynDOLOD\lib\process';
uses 'DynDOLOD\lib\create';
uses 'DynDOLOD\lib\functions';

const
  CellSize = 4096;
  IniPath = ScriptsPath + 'DynDOLOD\';
  AdvancedPath = ScriptsPath + 'DynDOLOD\DynDOLOD_';
  CachePath = ScriptsPath + 'DynDOLOD\cache\DynDOLOD_';

  sGridOptions = ',Near LOD,Near Full,Far LOD,Far Full,Never Fade LOD,Never Fade Full';
  iGridNone = 0;
  iGridNearLOD = 1;
  iGridNearFull = 2;
  iGridFarLOD = 3;
  iGridFarFull = 4;
  iGridNeverFadeLOD = 5;
  iGridNeverFadeFull = 6;

  sReferenceOptions = 'Unchanged,Replace,Disable,Keep';
  iReferenceUnchanged = 0;
  iReferenceReplace = 1;
  iReferenceDisable = 2;
  iReferenceKeep = 3;

  // LODGen
  sLODOptions = ',Full model,Static LOD4,Static LOD8,Static LOD16,_FAR model';
  iLODNone = 0;
  iLODFull = 1;
  iLOD4 = 2;
  iLOD8 = 3;
  iLOD16 = 4;
  iLODFar = 5;
  // LODGen

  iAtlasAverageTextureSize = 256;

type
  TWorld = Record
  XMin : int;
  YMin : int;
  XMax : int;
  YMax : int;
end;

var
  slGridTypes, slReferenceTypes, slFolders, slLODVanilla, slLODs, slBaseSignatures, slLODFiles, slDynDOLODFiles, slTownNames, slTownSTATEDIDIgnore, slMODLDynDOLOD, slModNameIgnore, slModNameWarn, slIgnoreBSAName, slCellsWithObjects, slTownsWithFirstborns, slMissingTrees, slTexturesNames, slMODLTextureSet, slChildWorldIgnore: TStringList;
  olEDIDExists, olEDIDFormID, olSignatureFormID, olSTATDAMT, olMODLFileBaseElement, olBaseElementDynDOLOD, olREFRDynDOLOD, olREFRTown, olMODLCache, olREFRWorld, slRulesCache, olCNAMCache, olXCLCCache, olFirstborns, olMinions, olFirstbornsIndex, olMinionsIndex, olBrotherIndex, slFirstbornsFormList, slMinionsFormList, olJsonObjectData: TwbFastStringList;
  lstSkipDynDOLOD, slREFRToDisable, slREFRTREELOD, slLODMeshes: TwbFastStringList; //TList;
  SkyrimWorld, SkyrimWorldUsed: TWorld;
  NEWFile: IInterface;
  sWorld, sThisWorld, sDynDOLODFileName, sSKSEPluginPath, sCurrentModName: string;
  MasterGridsToLoad, MinionGridsToLoad: Cardinal;
  bDebug, bAdvanced, bCreateMod, bSTATOnly, bUseCache, bUseTreeCache, bUseOrgLOD, bUpdateWRLD, bUpdateDDOL, bExecuteLODGenPas, bExecuteLODGenExe, fExport, bLODChildOrSelf, bCreateAtlas, bIgnoreTrees: Boolean;
  edMinion, edMaster, edSKSEPluginPath: TEdit;
  btnSKSEPluginPath, btnLow, btnMedium, btnHigh, btnUnpackLOD, btnLODGenExe, btnCreateAtlas: TButton;
  chkUseCache, chkUseTreeCache, chkUseOrgLOD, chkDoDynDOLOD, chkCreateAtlas: TCheckBox;
  LoadOrderCount, iTotalFiles, iFirstbornCounter, iMinionCounter, iDynDOLODCounter, iCellsWithObjectsCounter: integer;
  time : TDateTime;

  // LODGen
  slLODTypes, slLOD, slCache, slExport: TStringList;
  slLODAssets: TwbFastStringList;
  lstSkip: TList;
  LODGenWorld: IInterface;
  LODGenExport, LODGenParams: string;
  sTitle, sExport, sDestination, sDataPath: string;
  
  frm: TForm;
  btnOk, btnCancel, btnSave, btnLoad, btnDefault, btnExport, btnDestination, btnDataPath: TButton;
  btnUnpackLandscape: TButton;
  cbWorld, cbLODLevel, cbLODX, cbLODY: TComboBox;
  lvRules: TListView;
  SelectedRuleIndex: integer;
  chkDontFixTangents, chkNoTangents, chkNoColors, chkNoMaterial: TCheckBox;
  chkRemoveUnseen, chkIgnoreWater: TCheckBox;
  edExport, edDestination, edDataPath, edLODScale: TEdit;
  // LODGen


//============================================================================
function Initialize: integer;
var
  i, btn: integer;
  sl: TStringList;
begin
  Result := 0;

  bDebug := false;
  bCreateMod := false;
  bAdvanced := false;

  time := Now;
  LoadOrderCount := GetLoadOrder(FileByIndex(Pred(FileCount)));
  fExport := False;

  sTitle := 'DynDOLOD Worlds using ' + wbAppName + 'LODGen by Ehamloptiran, Sheson and Zilav';
  AddMessage('');
  AddMessage(sTitle + ', starting...');
  AddMessage('');

  // Set up LODGen and get options
  LODGenPrepare;

  // Set up DynDOLOD vars
  DynDOLODPrepare;

  // Show options form
  LODGenOptionsForm;

  time := Now;

  // no world selected or cancel
  if not Assigned(LODGenWorld) then
    Exit;

  // Set up DynDOLODWorld vars
  if not DynDOLODPrepareWorld then
    Exit;

  if bExecuteLODGenPas then begin
    // LODGen
    fExport := not FileExists(sExport);
    if not fExport then
      btn := MessageDlg('LOD export file already exists. Do you want to reexport LOD data?'#13'Clicking no means no new export list and no LODGen.exe execution!', mtConfirmation, [mbYes, mbNo, mbCancel], 0);
      if btn = mrCancel then
        Exit;
      if btn = mrYes then
        fExport := True;
    // LODGen
    time := Now;
  end;

  // build list of original LOD meshes
  // no need atm
  //BSALODFileList(True);

  // load data into lists
  LoadAdditionalLists;

  // build list of trees with LOD
  if not bCreateMod and not bIgnoreTrees then
    TreeWorldspace(sWorld);

  // get existing data
  if not ReadMasterFile then
    Exit;

  // get nifs
  ScanFiles;

  // prepare LOD
  if not bCreateMod then
    DoManualDynDOLODSTAT;
  DoBaseElements;

  if bCreateMod then
    Exit;

  // scan and update the world for objects
  if bUpdateWRLD then begin
    ScanWorlds(LODGenWorld)
  end;

  // add new LOD objects from child towns to parent world and create their LOD
  if bUpdateWRLD and (olREFRTown.Count > 0) then begin
    AddTownREFR;
  end;

  // export LODGen list
  if bExecuteLODGenPas then
    fExport := LODGenExportWorldspaceEnd(LODGenWorld);

  // usefull for debugging
  //AddMessage('saving lists');
  //slCellsWithObjects.SaveToFile(CachePath + sWorld + '_Firstborns.txt');
  //SaveOSLToFile2(olEDIDFormID, sWorld + 'DDOLFID');
  //SaveOSLToFile(olREFRDynDOLOD, sWorld + 'DynREFR');
  //AddMessage('loading lists');
  //slCellsWithObjects.LoadFromFile(CachePath + sWorld + '_Firstborns.txt');
  //olEDIDFormID := LoadOSLFromFile2(sWorld + 'DDOLFID');
  //olREFRDynDOLOD := LoadOSLFromFile(sWorld + 'DynREFR');

  // create texture atlas
  if not bCreateMod and bCreateAtlas then 
    CreateAtlas(True);

  // execute LODGen.exe
  if bExecuteLODGenPas and fExport then begin
    if bExecuteLODGenExe then
      ExecuteLODGen;
    // LODGen
  end;
  LODGenFree;

  // create Grids, REFR data, form lists for DynDOLOD Mod
  if (bUpdateWRLD and bUpdateDDOL) then begin
    DynDOLODCreate;
  end;

  // disable references
  DoDisables;

  // clean up
  FreeLists;

end;

end.

