private GameObject InstantiateRootNiObject(NiObject obj) { var gameObject = InstantiateNiObject(obj); bool shouldAddMissingColliders, isMarker; ProcessExtraData(obj, out shouldAddMissingColliders, out isMarker); if ((file.name != null) && IsMarkerFileName(file.name)) { shouldAddMissingColliders = false; isMarker = true; } // Add colliders to the object if it doesn't already contain one. if (shouldAddMissingColliders && (gameObject.GetComponentInChildren <Collider>() == null)) { GameObjectUtils.AddMissingMeshCollidersRecursively(gameObject); } if (isMarker) { GameObjectUtils.SetLayerRecursively(gameObject, MorrowindEngine.markerLayer); } return(gameObject); }
void ProcessExtraData(NiObject obj, out bool shouldAddMissingColliders, out bool isMarker) { shouldAddMissingColliders = true; isMarker = false; if (obj is NiObjectNET objNET) { var extraData = objNET.ExtraData.Value >= 0 ? (NiExtraData)_obj.Blocks[objNET.ExtraData.Value] : null; while (extraData != null) { if (extraData is NiStringExtraData strExtraData) { if (strExtraData.Str == "NCO" || strExtraData.Str == "NCC") { shouldAddMissingColliders = false; } else if (strExtraData.Str == "MRK") { shouldAddMissingColliders = false; isMarker = true; } } // Move to the next NiExtraData. extraData = extraData.NextExtraData.Value >= 0 ? (NiExtraData)_obj.Blocks[extraData.NextExtraData.Value] : null; } } }
private void FixReferences(NiObject obj) { var fields = obj.GetType().GetFields(); for (var i = 0; i < fields.Length; i++) { var fieldInfo = fields[i]; var fieldType = fieldInfo.FieldType.IsArray ? fieldInfo.FieldType.GetElementType() : fieldInfo.FieldType; if (typeof(INiRef).IsAssignableFrom(fieldType)) { if (fieldInfo.FieldType.IsArray) { var array = (INiRef[])fieldInfo.GetValue(obj); Array.ForEach(array, e => e.SetRef(this)); } else { ((INiRef)fieldInfo.GetValue(obj)).SetRef(this); } } } }
public int AddBlock(NiObject obj) { this.blocks.Add(obj); this.rawBlocks.Add(new byte[0]); this.blockType.Add(""); this.blockSize.Add(0); this.header.AddBlock(this.header, obj); return(this.blocks.Count - 1); }
/// <summary> /// Get Objects from Int Array. /// </summary> /// <param name="points">Pointers</param> /// <returns>Objects that the pointers pointed to.</returns> public IEnumerable <NiObject> FromIntArray(int[] points) { var arr = new NiObject[points.Length]; for (var i = 0; i < points.Length; i++) { arr[i] = this[points[i]]; } return(arr); }
private IEnumerable <NiObject> FromIntArray(IReadOnlyList <int> array) { var list = new NiObject[array.Count]; for (var i = 0; i < array.Count; i++) { list[i] = _niFile[array[i]]; } return(list); }
private bool TryExtractTriShape(NiObject obj, Matrix4 worldMatrix, bool invertTris, bool both, ref Vector3[] vertices, ref Triangle[] outtriangles) { var shape = obj as NiTriShape; if (shape == null) { return(false); } eFaceDrawMode mode = FindDrawMode(shape); if (mode == eFaceDrawMode.DRAW_CCW_OR_BOTH) { mode = both ? eFaceDrawMode.DRAW_BOTH : eFaceDrawMode.DRAW_CCW; } Matrix4 myMatrix = ComputeWorldMatrix(shape) * worldMatrix; var data = shape.Data.Object as NiTriShapeData; if (data.Triangles.Length == 0) { return(false); } vertices = new Vector3[data.Vertices.Length]; for (int i = 0; i < data.Vertices.Length; i++) { vertices[i] = Vector3.Transform(data.Vertices[i], myMatrix); } var triangles = new List <Triangle>(); // CCW if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CCW) != invertTris) { for (int i = 0; i < data.Triangles.Length; i++) { triangles.Add(new Triangle(data.Triangles[i].Z, data.Triangles[i].Y, data.Triangles[i].X)); } } // CC if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CW) != invertTris) { triangles.AddRange(data.Triangles); } outtriangles = triangles.ToArray(); return(true); }
void AddColliderFromNiObject(NiObject niObject, GameObject gameObject) { if (niObject.GetType() == typeof(NiTriShape)) { var colliderObj = InstantiateNiTriShape((NiTriShape)niObject, false, true); colliderObj.transform.SetParent(gameObject.transform, false); } else if (niObject.GetType() == typeof(AvoidNode)) { } else { Log("Unsupported collider NiObject: " + niObject.GetType().Name); } }
/// <summary> /// Creates a GameObject representation of an NiObject. /// </summary> /// <returns>Returns the created GameObject, or null if the NiObject does not need its own GameObject.</returns> GameObject InstantiateNiObject(NiObject obj) { if (obj.GetType() == typeof(NiNode)) { return(InstantiateNiNode((NiNode)obj)); } else if (obj.GetType() == typeof(NiBSAnimationNode)) { return(InstantiateNiNode((NiNode)obj)); } else if (obj.GetType() == typeof(NiTriShape)) { return(InstantiateNiTriShape((NiTriShape)obj, true, false)); } else if (obj.GetType() == typeof(RootCollisionNode)) { return(InstantiateRootCollisionNode((RootCollisionNode)obj)); } else if (obj.GetType() == typeof(NiTextureEffect)) { return(null); } else if (obj.GetType() == typeof(NiBSAnimationNode)) { return(null); } else if (obj.GetType() == typeof(NiBSParticleNode)) { return(null); } else if (obj.GetType() == typeof(NiRotatingParticles)) { return(null); } else if (obj.GetType() == typeof(NiAutoNormalParticles)) { return(null); } else if (obj.GetType() == typeof(NiBillboardNode)) { return(null); } else { throw new NotImplementedException($"Tried to instantiate an unsupported NiObject ({obj.GetType().Name})."); } }
GameObject InstantiateRootNiObject(NiObject obj) { var gameObject = InstantiateNiObject(obj); ProcessExtraData(obj, out var shouldAddMissingColliders, out var isMarker); if (_obj.Name != null && IsMarkerFileName(_obj.Name)) { shouldAddMissingColliders = false; isMarker = true; } // Add colliders to the object if it doesn't already contain one. if (shouldAddMissingColliders && gameObject.GetComponentInChildren <Collider>() == null) { GameObjectUtils.AddMissingMeshCollidersRecursively(gameObject); } if (isMarker) { GameObjectUtils.SetLayerRecursively(gameObject, _markerLayer); } return(gameObject); }
private void ProcessExtraData(NiObject obj, out bool shouldAddMissingColliders, out bool isMarker) { shouldAddMissingColliders = true; isMarker = false; if (obj is NiObjectNET) { var objNET = (NiObjectNET)obj; var extraData = (objNET.extraData.value >= 0) ? (NiExtraData)file.blocks[objNET.extraData.value] : null; while (extraData != null) { if (extraData is NiStringExtraData) { var strExtraData = (NiStringExtraData)extraData; if (strExtraData.str == "NCO" || strExtraData.str == "NCC") { shouldAddMissingColliders = false; } else if (strExtraData.str == "MRK") { shouldAddMissingColliders = false; isMarker = true; } } // Move to the next NiExtraData. if (extraData.nextExtraData.value >= 0) { extraData = (NiExtraData)file.blocks[extraData.nextExtraData.value]; } else { extraData = null; } } } }
public void Read(string gameDir, string fileName, LogFile logFile) { MemoryStream memoryStream = new MemoryStream(); try { if (File.Exists(gameDir + fileName)) { try { FileStream fileStream = (FileStream)null; while (fileStream == null) { fileStream = Utils.GetFileStream(new FileInfo(gameDir + fileName), logFile); } BinaryReader binaryReader = new BinaryReader((Stream)fileStream); long length = binaryReader.BaseStream.Length; memoryStream.Write(binaryReader.ReadBytes((int)length), 0, (int)length); binaryReader.Close(); //logFile.WriteLog(" read " + fileName + " " + length); } catch (Exception ex) { logFile.WriteLog("Error reading " + fileName + " " + ex.Message); logFile.Close(); System.Environment.Exit(500); } } else if (BSAArchive.FileExists(fileName)) { try { byte[] newfile = BSAArchive.GetFile(fileName); int length = newfile.Length; memoryStream.Write(newfile, 0, length); } catch (Exception ex) { logFile.WriteLog("Error reading " + fileName + " from BSA/BA2 " + ex.Message + ex.Source); if (ex.Source.ToLower().Contains("mscorlib")) { logFile.WriteLog("Install Visual C++ Redistributable for Visual Studio 2015 from https://www.microsoft.com/en-us/download/details.aspx?id=48145"); } logFile.Close(); System.Environment.Exit(501); } } else { logFile.WriteLog(fileName + " not found"); logFile.Close(); System.Environment.Exit(404); } } catch (Exception ex) { logFile.WriteLog("Error accessing " + gameDir + fileName + " " + ex.Message); logFile.WriteLog("In case Mod Organizer is used, set output path outside of game and MO virtual file system directory"); logFile.Close(); System.Environment.Exit(502); } memoryStream.Position = 0L; BinaryReader reader = new BinaryReader((Stream)memoryStream); string error = "Read error " + fileName; try { this.header.Read(reader); var stream = reader.BaseStream; for (int index = 0; (long)index < (long)this.header.GetNumBlocks(); ++index) { //Console.WriteLine("Reading block " + index + " of " + this.header.GetNumBlocks() + " = " + stream.Position + " = " + this.header.GetBlockTypeAtIndex(index)); if (NiFile.classTypes.ContainsKey(this.header.GetBlockTypeAtIndex(index))) { NiObject niObject = (NiObject)Activator.CreateInstance(NiFile.classTypes[this.header.GetBlockTypeAtIndex(index)]); niObject.Read(this.header, reader); this.blocks.Add(niObject); this.rawBlocks.Add(new byte[0]); this.blockType.Add(this.header.GetBlockTypeAtIndex(index)); this.blockSize.Add(this.header.GetBlockSizeAtIndex(index)); } else { error = "Unsupported block " + index + " " + this.header.GetBlockTypeAtIndex(index) + " in " + gameDir + fileName; //logFile.WriteLog("Unsupported block " + index + " " + this.header.GetBlockTypeAtIndex(index) + " in " + gameDir + fileName); uint blockSizeAtIndex = this.header.GetBlockSizeAtIndex(index); this.blocks.Add((NiObject)null); this.rawBlocks.Add(reader.ReadBytes((int)blockSizeAtIndex)); this.blockType.Add(this.header.GetBlockTypeAtIndex(index)); this.blockSize.Add(this.header.GetBlockSizeAtIndex(index)); } } } catch { logFile.WriteLog(error); //logFile.Close(); //System.Environment.Exit(501); } reader.Close(); }
private bool TryExtractTriStrips(NiObject obj, Matrix4 worldMatrix, bool invertTris, bool both, ref Vector3[] vertices, ref Triangle[] outtriangles) { var strips = obj as NiTriStrips; if (strips == null) { return(false); } eFaceDrawMode mode = FindDrawMode(strips); if (mode == eFaceDrawMode.DRAW_CCW_OR_BOTH) { mode = both ? eFaceDrawMode.DRAW_BOTH : eFaceDrawMode.DRAW_CCW; } Matrix4 myMatrix = ComputeWorldMatrix(strips) * worldMatrix; var data = strips.Data.Object as NiTriStripsData; if (data.Vertices.Length == 0) { return(false); } vertices = new Vector3[data.Vertices.Length]; for (int i = 0; i < data.Vertices.Length; i++) { vertices[i] = Vector3.Transform(data.Vertices[i], myMatrix); } var triangles = new List <Triangle>(); foreach (var points in data.Points) { // CCW if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CCW) != invertTris) { ushort a = points[0]; ushort b = points[0]; ushort c = points[1]; bool flip = false; for (int s = 2; s < points.Length; s++) { a = b; b = c; c = points[s]; if (a != b && b != c && c != a) { triangles.Add(!flip ? new Triangle(a, c, b) : new Triangle(a, b, c)); } flip = !flip; } } // CC if (mode == eFaceDrawMode.DRAW_BOTH || (mode == eFaceDrawMode.DRAW_CW) != invertTris) { ushort a = points[0]; ushort b = points[0]; ushort c = points[1]; bool flip = false; for (int s = 2; s < points.Length; s++) { a = b; b = c; c = points[s]; if (a != b && b != c && c != a) { triangles.Add(!flip ? new Triangle(a, b, c) : new Triangle(a, c, b)); } flip = !flip; } } } outtriangles = triangles.ToArray(); return(true); }
internal bool Update(float diff, float totalTime) { if (this.WantState > 0 && !this.TriedToLoadMarker) { this.TriedToLoadMarker = true; NiObject.LoadFromFileAsync(new NiObjectLoadParameters() { Callback = p => { if (p.Success) { var obj = p.Result[0] as NiAVObject; if (obj != null) { this.Object = obj; this.Object.IncRef(); this.Object.LocalTransform.Scale = this.MarkerScale; } } this.DidLoadMarker = true; }, Count = 1, FileName = this.MarkerNif }); } if (!this.DidLoadMarker) { return(true); } if (this.WantState > 0 && this.Object != null) { this.WantState = 0; this.CurrentFade = 0.0f; this.WantFade = 1.0f; this.SetCurrentFade(0.0f); this.AddToWorld(); } else if (this.WantState < 0) { this.WantFade = 0.0f; } if (this.Object != null) { this.UpdateFade(diff); this.SetCurrentFade(this.CurrentFade); } if (this.Object != null && this.IsInWorld() && this.WantState < 0 && this.CurrentFade > 0.0f) { this.UpdateObject(totalTime); } if (this.WantState < 0 && this.CurrentFade <= 0.0f) { this.Free(); return(false); } return(true); }
internal void Initialize() { if (this.Marker == null && !this.TriedToLoadMarker) { this.TriedToLoadMarker = true; NiObject.LoadFromFileAsync(new NiObjectLoadParameters() { Callback = p => { if (p.Success) { var obj = p.Result[0].As <NiAVObject>(); if (obj != null) { this.Marker = obj; this.Marker.IncRef(); this.Marker.LocalTransform.Scale = this.Plugin.Settings.MarkerScale; } } }, Count = 1, FileName = this.Plugin.Settings.MarkerNif }); } var alloc = Memory.Allocate(0x110); alloc.Pin(); this.TargetMarkerPoint = MemoryObject.FromAddress <NiPoint3>(alloc.Address); this.TargetTeleportPoint = MemoryObject.FromAddress <NiPoint3>(alloc.Address + 0x10); this.AimVectorPoint = MemoryObject.FromAddress <NiPoint3>(alloc.Address + 0x20); this.SourceTeleportPoint = MemoryObject.FromAddress <NiPoint3>(alloc.Address + 0x30); this.CurrentTeleportPoint = MemoryObject.FromAddress <NiPoint3>(alloc.Address + 0x40); this.AimVectorPointDoubled = MemoryObject.FromAddress <NiPoint3>(alloc.Address + 0x50); this.ThirdPersonTempTransform = MemoryObject.FromAddress <NiTransform>(alloc.Address + 0x60); this.SourceMovePoint = MemoryObject.FromAddress <NiPoint3>(alloc.Address + 0x100); this.AimVectorPoint.X = 0.0f; this.AimVectorPoint.Z = 0.0f; this.AimVectorPoint.Y = Math.Max(100.0f, Math.Min(8000.0f, this.Plugin.Settings.MaxDistance)); this.AimVectorPointDoubled.X = 0.0f; this.AimVectorPointDoubled.Z = 0.0f; this.AimVectorPointDoubled.Y = 2000.0f + Math.Max(100.0f, Math.Min(8000.0f, this.Plugin.Settings.MaxDistance)); // Setup GameOffset - Updated PrepareFunction & InstallHook to take this value, I didn't update directly incase some use a different Offset. int GameOffset = 0x0; // Everything is based from 1_5_62 var GameVersion = NetScriptFramework.Main.Game.GameVersion; // Get the game version if (GameVersion[0] == 1 && GameVersion[1] == 5 && GameVersion[2] >= 73 && GameVersion[2] <= 97) { GameOffset = 0x1F0; // Check for game version 1_5_73 to 1_5_97, update GameOffset } var debug = CrashLog.Debug; DebugInfo.DebugFunctionInfo fn = null; if (debug == null || (fn = debug.GetFunctionInfo(36319)) == null) { throw new InvalidOperationException(this.Plugin.Name + " can't work without a debug library!"); } this.fn_Actor_SetPosition = new IntPtr(((long)(debug.BaseOffset + fn.Begin) - (uint)GameOffset)); fn = debug.GetFunctionInfo(32301); if (fn != null) { this.fn_BGSSoundDescriptor_PlaySound = new IntPtr(((long)(debug.BaseOffset + fn.Begin) - (uint)GameOffset)); } fn = debug.GetFunctionInfo(18185); if (fn != null) { this.fn_TESImageSpaceModifier_Apply = new IntPtr(((long)(debug.BaseOffset + fn.Begin) - (uint)GameOffset)); } fn = debug.GetFunctionInfo(51907); if (fn != null) { this.fn_FlashHudMeter = new IntPtr(((long)(debug.BaseOffset + fn.Begin) - (uint)GameOffset)); } fn = debug.GetFunctionInfo(11295); if (fn != null) { this.fn_GetMagicFailedMessage = new IntPtr(((long)(debug.BaseOffset + fn.Begin) - (uint)GameOffset)); } /*var cost = this.Plugin.Settings.MagickaCost; * if (cost > 0.0f) * { * var spell = this.Plugin.Settings.SpellForm; * if (spell != null) * { * var effectItem = Memory.ReadPointer(spell.Address + 0x58); * if (effectItem != IntPtr.Zero) * { * effectItem = Memory.ReadPointer(effectItem); * if (effectItem != IntPtr.Zero) * { * var effect = MemoryObject.FromAddress<EffectSetting>(Memory.ReadPointer(effectItem + 0x10)); * if (effect != null) * Memory.WriteFloat(effect.Address + 0x6C, cost); * * Memory.WriteFloat(effectItem + 0x18, cost); * } * } * * Memory.WriteInt32(spell.Address + 0xC0, (int)(cost + 0.1f)); * } * }*/ }
public int AddBlock(NiObject obj) { this.blocks.Add(obj); this.header.AddBlock(obj); return(this.blocks.Count - 1); }
public void Read(string skyrimDir, string fileName, LogFile logFile) { MemoryStream memoryStream = new MemoryStream(); if (File.Exists(skyrimDir + fileName)) { try { FileStream fileStream = (FileStream)null; while (fileStream == null) { fileStream = Utils.GetFileStream(new FileInfo(skyrimDir + fileName), logFile); } BinaryReader binaryReader = new BinaryReader((Stream)fileStream); long length = binaryReader.BaseStream.Length; memoryStream.Write(binaryReader.ReadBytes((int)length), 0, (int)length); binaryReader.Close(); //logFile.WriteLog(" read " + fileName + " " + length); } catch (Exception ex) { logFile.WriteLog("Error reading " + fileName + " " + ex.Message); logFile.Close(); System.Environment.Exit(500); } } else if (BSAArchive.FileExists(fileName)) { try { //logFile.Console.WriteLine(" reading " + fileName + " from BSA"); byte[] newfile = BSAArchive.GetFile(fileName); int length = newfile.Length; memoryStream.Write(newfile, 0, length); //logFile.WriteLog(" read " + fileName + " " + length + " from BSA"); } catch (Exception ex) { logFile.WriteLog("Error reading " + fileName + " from BSA " + ex.Message); logFile.Close(); System.Environment.Exit(501); } } else { logFile.WriteLog(fileName + " not found"); logFile.Close(); System.Environment.Exit(404); } memoryStream.Position = 0L; //Console.WriteLine("Reading " + fileName); BinaryReader reader = new BinaryReader((Stream)memoryStream); this.header.Read(reader); for (int index = 0; (long)index < (long)this.header.GetNumBlocks(); ++index) { if (NiFile.classTypes.ContainsKey(this.header.GetBlockTypeAtIndex(index))) { NiObject niObject = (NiObject)Activator.CreateInstance(NiFile.classTypes[this.header.GetBlockTypeAtIndex(index)]); niObject.Read(this.header, reader); this.blocks.Add(niObject); } else { uint blockSizeAtIndex = this.header.GetBlockSizeAtIndex(index); reader.ReadBytes((int)blockSizeAtIndex); this.blocks.Add((NiObject)null); } } reader.Close(); //Console.WriteLine("done " + fileName); }