private void WalkNodes(NiAVObject node) { if (!IsValidNode(node)) { return; } // Render Children if (node is NiTriShape) { ParseShape((NiTriShape)node); } else if (node is NiTriStrips) { ParseStrips((NiTriStrips)node); } NiNode currentNode = node as NiNode; if (currentNode != null) { if (currentNode.Children.Length > 0) { foreach (var child in currentNode.Children) { if (child.IsValid()) { WalkNodes(child.Object); } } } } }
private float[] GetCollisionPointFromCamera(NiNode cameraNode, TESObjectCELL cell, NiAVObject[] ignore) { float[] source = new float[3]; float[] target = new float[3]; var nodePos = cameraNode.WorldTransform.Position; source[0] = nodePos.X; source[1] = nodePos.Y; source[2] = nodePos.Z; cameraNode.WorldTransform.Translate(this.AimVectorPointDoubled, this.TargetTeleportPoint); target[0] = this.TargetTeleportPoint.X; target[1] = this.TargetTeleportPoint.Y; target[2] = this.TargetTeleportPoint.Z; var ray = this.DoRayCast(cell, source, target); var best = this.GetBestResult(source, ray, ignore, false); if (best == null) { return(target); } return(best.Position); }
/// <summary> /// Search Ninode Category From given Root /// </summary> /// <param name="node"></param> /// <param name="category"></param> /// <returns></returns> public static NiNode[] FindNodeWithCategory(this NiNode node, string category) { var result = new List <NiNode>(); var stack = new Stack <NiNode>(); stack.Push(node); do { var current = stack.Pop(); if (Regex.IsMatch(current.Name.Value, category, RegexOptions.IgnoreCase)) { // Add Result and Don't Push Children ! result.Add(current); } else if (current.Children != null) { foreach (var child in current.Children.Where(rf => rf.IsValid()).Select(rf => rf.Object).OfType <NiNode>()) { stack.Push(child); } } }while (stack.Count > 0); return(result.ToArray()); }
/// <summary> /// Get Triangle From Node Root Retrieving Geometry Based Meshes /// </summary> /// <param name="node"></param> /// <param name="onlyDrawable"></param> /// <returns></returns> public static TriangleCollection GetTrianglesFromNode(this NiNode node, bool onlyDrawable = false) { var stack = new Stack <NiNode>(); stack.Push(node); TriangleCollection result = new TriangleCollection { Vertices = new Vector3[0], Indices = new TriangleIndex[0], }; foreach (var trinode in node.GetTriBasedNode()) { // Filter drawable nodes if (onlyDrawable && trinode.IsInvisible()) { continue; } var triangles = trinode.GetTrianglesFromGeometry(); TriangleCollection intermediate; Concat(ref result, ref triangles, out intermediate); result = intermediate; } return(result); }
private void BuildHierarchy(NiNode node, GameObject parent) { var obj = SpawnAvObject(node, parent); _unityObjects.Add(node, obj); if (_animationRoot == null) { _animationRoot = obj.transform; } foreach (var child in _niFile.FromIntArray(node.Children)) { switch (child) { case NiNode childNode: BuildHierarchy(childNode, obj); break; case NiAVObject childAvObject: SpawnAvObject(childAvObject, obj); break; default: Debug.Log($"Unhandled NiObject: {child}"); break; } } }
private void ExploreEquipment(NiNode root, NiAVObject current, List <NiAVObject> ls) { // Special case, we should ignore and stop looking here, head is handled elsewhere. if (current != null) { var nm = current.Name.Text ?? ""; if (nm.Equals("BSFaceGenNiNodeSkinned", StringComparison.OrdinalIgnoreCase)) { return; } } if (current is BSGeometry) { var g = (BSGeometry)current; var skin = g.Skin.Value; if (skin != null && skin is BSDismemberSkinInstance) { var count = Memory.ReadInt32(skin.Address + 0x88); if (count > 0) { var pbuf = Memory.ReadPointer(skin.Address + 0x90); if (pbuf != IntPtr.Zero) { var isHelm = false; for (var i = 0; i < count; i++) { int m = Memory.ReadUInt16(pbuf + (4 * i + 2)); if (NotHelmetBipedMask[m]) { isHelm = false; break; } if (IsHelmetBipedMask[m]) { isHelm = true; } } if (isHelm) { ls.Add(current); } } } } } if (current is NiNode) { var n = current as NiNode; foreach (var ch in n.Children) { ExploreEquipment(root, ch, ls); } } }
private List <NiAVObject> GetHelmetNodes(NiNode root) { var ls = new List <NiAVObject>(); if (root != null) { this.FillValidBipedObjects(root, ls); } return(ls); }
private void InitMagicNode() { if (MagicNodeAllocation != null) { return; } const int count = 3; const int size = 0x130; const int size2 = 0x10; MagicNodeAllocation = Memory.Allocate(size * count + size2 * count); MagicNodes = new NiNode[count]; MagicTranslates = new NiPoint3[count]; var s = Settings.Instance; for (var i = 0; i < count; i++) { var addrOfThis = MagicNodeAllocation.Address + size * i; Memory.InvokeCdecl(Plugin.NiNode_ctor, addrOfThis, 0); MagicNodes[i] = MemoryObject.FromAddress <NiNode>(addrOfThis); MagicNodes[i].IncRef(); MagicTranslates[i] = MemoryObject.FromAddress <NiPoint3>(MagicNodeAllocation.Address + size * count + size2 * i); switch (i) { case 0: MagicTranslates[i].X = s.MagicLeftOffsetX; MagicTranslates[i].Y = s.MagicLeftOffsetY; MagicTranslates[i].Z = s.MagicLeftOffsetZ; break; case 1: MagicTranslates[i].X = s.MagicRightOffsetX; MagicTranslates[i].Y = s.MagicRightOffsetY; MagicTranslates[i].Z = s.MagicRightOffsetZ; break; case 2: MagicTranslates[i].X = s.MagicVoiceOffsetX; MagicTranslates[i].Y = s.MagicVoiceOffsetY; MagicTranslates[i].Z = s.MagicVoiceOffsetZ; break; default: MagicTranslates[i].X = 0.0f; MagicTranslates[i].Y = 0.0f; MagicTranslates[i].Z = 0.0f; break; } } }
public void Load(Stream source_stream) { NiHeader header = GetHeader(source_stream); header.Dump(); int bt_NiTriShapeData = header.GetBlockTypeIdxByName("NiTriShapeData"); int bt_BSLightingShaderProperty = header.GetBlockTypeIdxByName("BSLightingShaderProperty"); int bt_BSShaderTextureSet = header.GetBlockTypeIdxByName("BSShaderTextureSet"); int bt_NiSkinInstance = header.GetBlockTypeIdxByName("NiSkinInstance"); int bt_NiSkinPartition = header.GetBlockTypeIdxByName("NiSkinPartition"); int num_blocks = header.blocks.Length; for (int i = 0; i < num_blocks; i++) { if (header.blocks[i].type == bt_NiTriShapeData) { NiTriShapeData triShapeData = GetObject <NiTriShapeData>(header, i); triShapeData.Dump(); } if (header.blocks[i].type == bt_BSLightingShaderProperty) { BSLightingShaderProperty lightingShaderProperty = GetObject <BSLightingShaderProperty>(header, i); lightingShaderProperty.Dump(); } if (header.blocks[i].type == bt_BSShaderTextureSet) { BSShaderTextureSet shaderTextureSet = GetObject <BSShaderTextureSet>(header, i); shaderTextureSet.Dump(); } if (header.blocks[i].type == bt_NiSkinInstance) { NiSkinInstance skinInstance = GetObject <NiSkinInstance>(header, i); skinInstance.Dump(); foreach (ObjectRef boneref in skinInstance.bones) { NiNode node = GetObject <NiNode>(header, boneref); System.Console.WriteLine(header.strings[node.name]); } } if (header.blocks[i].type == bt_NiSkinPartition) { NiSkinPartition skinPartition = GetObject <NiSkinPartition>(header, i); skinPartition.Dump(); } } }
static GameObject processNodeAndLinkToParent(NIFFile nf, NiNode niNode, GameObject parent, bool skinMesh) { GameObject goM = new GameObject(); goM.name = niNode.name; foreach (NiMesh mesh in nf.getMeshes()) { if (mesh.parentIndex == niNode.index) { GameObject meshGo = processMesh(nf, mesh, nf.getMeshData(mesh), skinMesh); if (niNode is NiTerrainNode) { //meshGo.GetComponent<MeshRenderer>().material = new Material(Shader.Find("BasicTerrainShader")); //Debug.Log("found a terrain node"); } meshGo.transform.parent = goM.transform; meshGo.transform.localScale = new Vector3(mesh.scale, mesh.scale, mesh.scale); Quaternion q = GetRotation(toMat(mesh.matrix)); meshGo.transform.localRotation = q; //meshGo.transform.localEulerAngles = new Vector3(mesh.ma) } } nf.forEachChildNode(niNode.index, (obj) => processNodeAndLinkToParent(nf, obj, goM, skinMesh)); goM.transform.parent = parent.transform; // Terrain NIFs already have their location set in the parent node, we don't need to set it for the mesh. if (!(niNode is NiTerrainNode)) { goM.transform.localPosition = new Vector3(niNode.translation.x, niNode.translation.y, niNode.translation.z); Matrix4x4 mat = toMat(niNode.matrix); Quaternion q = GetRotation(mat); goM.transform.localRotation = q; //Debug.Log("[" + niNode.name + "]: trans:\n" + mat.GetRow(0) + "\n" + mat.GetRow(1) + "\n" + mat.GetRow(2) + "\n" + mat.GetRow(3)); //goM.transform.localEulerAngles = } else { } goM.transform.localScale = new Vector3(niNode.scale, niNode.scale, niNode.scale); //goM.transform.localRotation return(goM); }
public void SetNodeRefParent(ObjectRef node_ref, NiNode parent) { if (node_ref == -1) { return; } NiNode node = nodes[node_ref]; node.self_ref = node_ref; node.parent = parent; foreach (ObjectRef _node_ref in node.children) { SetNodeRefParent(_node_ref, node); } }
void DumpNodes() { int bt_NiNode = header.GetBlockTypeIdxByName("NiNode"); //Console.WriteLine("BT idx 'NiNode': {0}", bt_NiNode); int num_blocks = header.blocks.Length; nodes = new NiNode[num_blocks]; for (int i = 0; i < num_blocks; i++) { if (header.blocks[i].type == bt_NiNode) { using (MemoryStream stream = new MemoryStream(header.blocks[i].data)) { BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.Default); nodes[i] = new NiNode(); nodes[i].Read(reader); } } } int string_root = header.GetStringIdxByName("NPC Root [Root]"); //Console.WriteLine("String idx 'NPC Root [Root]': {0}", string_root); root_node_ref = -1; for (int i = 0; i < num_blocks; i++) { NiNode node = nodes[i]; if (node == null) { continue; } if (node.name == string_root) { root_node_ref = i; break; } } SetNodeRefParent(root_node_ref, null); DumpNodeRef(root_node_ref); }
GameObject InstantiateNiNode(NiNode node) { var obj = new GameObject(node.Name); foreach (var childIndex in node.Children) { // NiNodes can have child references < 0 meaning null. if (!childIndex.IsNull) { var child = InstantiateNiObject(_obj.Blocks[childIndex.Value]); if (child != null) { child.transform.SetParent(obj.transform, false); } } } ApplyNiAVObject(node, obj); return(obj); }
public void DumpNodeRef(ObjectRef node_ref) { if (node_ref == -1) { return; } NiNode node = nodes[node_ref]; if (!SharpDX.MathUtil.NearEqual(node.local.scale, 1.0f)) { Console.Write(GetString(node.name)); Console.WriteLine("\t{0:F6}", node.local.scale); } foreach (ObjectRef _node_ref in node.children) { DumpNodeRef(_node_ref); } }
TreeViewItem CreateTreeNodes(NiHeader hdr, int nodeIndex) { if (nodeIndex >= hdr.blocks.Length) { MessageBox.Show("Node (" + nodeIndex.ToString() + ") out of range."); return(null); } NiNode node = null; try { node = hdr.GetObject <NiNode>(nodeIndex); } catch (Exception) { return(null); } TreeViewItem branch = new TreeViewItem(); var textBlock = new TextBlock() { Text = hdr.GetNiNodeName(nodeIndex), }; textBlock.IsHitTestVisible = false; branch.Header = textBlock; if (node != null && node.children.Length > 0) { foreach (var childIndex in node.children) { var subBranch = CreateTreeNodes(hdr, childIndex); if (subBranch != null) { branch.Items.Add(subBranch); } } } return(branch); }
void CreateNodes() { int bt_NiNode = header.GetBlockTypeIdxByName("NiNode"); //Console.WriteLine("BT idx 'NiNode': {0}", bt_NiNode); int num_blocks = header.blocks.Length; nodes = new NiNode[num_blocks]; for (int i = 0; i < num_blocks; i++) { if (header.blocks[i].type == bt_NiNode) { using (MemoryStream stream = new MemoryStream(header.blocks[i].data)) { BinaryReader reader = new BinaryReader(stream, System.Text.Encoding.Default); nodes[i] = new NiNode(); nodes[i].Read(reader); } } } }
/// <summary> /// Retrieve Tri Based Nodes with 0f LoD Distance in all tree Depth /// </summary> /// <param name="node">Starting Lookup Node</param> /// <returns>NiTriBasedGeometry Collection</returns> public static IEnumerable <NiTriBasedGeometry> GetTriBasedNode(this NiNode node) { var stack = new Stack <NiNode>(); stack.Push(node); do { var current = stack.Pop(); var nilod = current as NiLODNode; if (nilod != null) { foreach (var child in nilod.GetChildrenFromLOD(0f)) { stack.Push(child); } } else { foreach (var child in current.GetChildren()) { var childNode = child as NiNode; if (childNode != null) { stack.Push(childNode); } var childGeom = child as NiTriBasedGeometry; if (childGeom != null) { yield return(childGeom); } } } }while(stack.Count > 0); yield break; }
private void UpdateHideWithCull(Actor actor, HideFlags want, NiNode root) { if (root == null) { return; } if ((want & HideFlags.Head) != HideFlags.None) { var node = root.LookupNodeByName("BSFaceGenNiNodeSkinned"); if (node != null) { this.LastFlags |= HideFlags.Head; this.CameraMain.Cull.AddDisable(node); this.LastHeadAddress = node.Address; } } if ((want & HideFlags.Head2) != HideFlags.None) { var node = root.LookupNodeByName("WereWolfLowHead01"); if (node != null) { this.LastFlags |= HideFlags.Head2; this.CameraMain.Cull.AddDisable(node); node = root.LookupNodeByName("WereWolfTeeth"); if (node != null) { this.CameraMain.Cull.AddDisable(node); } node = root.LookupNodeByName("EyesMaleWerewolfBeast"); if (node != null) { this.CameraMain.Cull.AddDisable(node); } } else { node = root.LookupNodeByName("NPC Head [Head]"); if (node != null) { this.LastFlags |= HideFlags.Head2; this.CameraMain.Cull.AddUnscale(node); } } } if ((want & HideFlags.Arms) != HideFlags.None) { var left = root.LookupNodeByName("NPC L UpperArm [LUar]"); var right = root.LookupNodeByName("NPC R UpperArm [RUar]"); if (left != null && right != null) { this.LastFlags |= HideFlags.Arms; this.CameraMain.Cull.AddUnscale(left); this.CameraMain.Cull.AddUnscale(right); } } if ((want & HideFlags.Helmet) != HideFlags.None) { this.InitializeHelmet(root, null); } }
private void UpdateAiming(float diff, float totalTime, PlayerCharacter plr, TESObjectCELL cell) { if (!this.IsMarkerInWorld) { return; } var camera = PlayerCamera.Instance; if (camera == null) { return; } var cameraNode = camera.Node; if (cameraNode == null) { return; } NiNode[] playerNode = new NiNode[2] { plr.GetSkeletonNode(false), plr.GetSkeletonNode(true) }; for (int i = 0; i < playerNode.Length; i++) { if (playerNode[i] == null) { return; } } { var plrPos = plr.Position; this.SourceMovePoint.X = plrPos.X; this.SourceMovePoint.Y = plrPos.Y; this.SourceMovePoint.Z = plrPos.Z; } if (camera.State != null && camera.State.Id == TESCameraStates.FirstPerson) { var plrPos = cameraNode.WorldTransform.Position; this.SourceTeleportPoint.X = plrPos.X; this.SourceTeleportPoint.Y = plrPos.Y; this.SourceTeleportPoint.Z = plrPos.Z; cameraNode.WorldTransform.Translate(this.AimVectorPoint, this.TargetTeleportPoint); } else { var headNode = playerNode[0].LookupNodeByName("NPC Head [Head]"); if (headNode != null) { var plrPos = headNode.WorldTransform.Position; this.SourceTeleportPoint.X = plrPos.X; this.SourceTeleportPoint.Y = plrPos.Y; this.SourceTeleportPoint.Z = plrPos.Z; } else { var plrPos = plr.Position; this.SourceTeleportPoint.X = plrPos.X; this.SourceTeleportPoint.Y = plrPos.Y; this.SourceTeleportPoint.Z = plrPos.Z + this.Plugin.Settings.PlayerRadius; } var cameraCol = this.GetCollisionPointFromCamera(cameraNode, cell, playerNode); byte[] data = Memory.ReadBytes(cameraNode.WorldTransform.Address, MemoryObject.SizeOf <NiTransform>()); Memory.WriteBytes(this.ThirdPersonTempTransform.Address, data); this.TargetTeleportPoint.X = cameraCol[0]; this.TargetTeleportPoint.Y = cameraCol[1]; this.TargetTeleportPoint.Z = cameraCol[2]; this.ThirdPersonTempTransform.LookAt(this.TargetTeleportPoint); this.ThirdPersonTempTransform.Translate(this.AimVectorPoint, this.TargetTeleportPoint); } bool allowWallClimb = true; { var source = new[] { this.SourceTeleportPoint.X, this.SourceTeleportPoint.Y, this.SourceTeleportPoint.Z }; var target = new[] { this.TargetTeleportPoint.X, this.TargetTeleportPoint.Y, this.TargetTeleportPoint.Z }; var ray = this.DoRayCast(cell, source, target); float[] collisionPosition = null; float[] collisionNormal = null; var best = this.GetBestResult(source, ray, playerNode, false); if (best == null) { collisionPosition = target; float[] revNormal = new float[3]; float rx = target[0] - source[0]; float ry = target[1] - source[1]; float rz = target[2] - source[2]; float rd = (float)Math.Sqrt(rx * rx + ry * ry + rz * rz); if (rd > 0.0f) { rx /= rd; ry /= rd; rz /= rd; } revNormal[0] = rx * -1.0f; revNormal[1] = ry * -1.0f; revNormal[2] = rz * -1.0f; collisionNormal = revNormal; allowWallClimb = false; } else { collisionPosition = best.Position; collisionNormal = best.Normal; float nlen = Length(collisionNormal); if (nlen > 0.0f) { collisionNormal[0] /= nlen; collisionNormal[1] /= nlen; collisionNormal[2] /= nlen; } if (!this.Plugin.Settings.AllowLedgeClimbNPC) { var hkObj = best.HavokObject; if (hkObj != IntPtr.Zero) { var layer = (CollisionLayers)(Memory.ReadUInt32(hkObj + 0x2C) & 0x7F); switch (layer) { case CollisionLayers.LivingAndDeadActors: case CollisionLayers.BipedNoCC: case CollisionLayers.CharController: allowWallClimb = false; break; } } } } float fullDist = Distance(collisionPosition, source); float ratioInc = 1.0f; if (fullDist > 0.0f) { ratioInc = Math.Max(10.0f, this.Plugin.Settings.TeleportIncrementalCheck) / fullDist; } ratioInc = Math.Max(0.02f, ratioInc); float ratioNow = 1.0f; float[] checkPos = new float[3]; bool ok = false; while (ratioNow > 0.0f) { for (int i = 0; i < 3; i++) { checkPos[i] = (collisionPosition[i] - source[i]) * ratioNow + source[i]; } float[] tpPos = null; float[] mrPos = null; if (this.CalculatePositionFromCollision(checkPos, collisionNormal, ref tpPos, ref mrPos, playerNode, cell, allowWallClimb)) { this.TargetTeleportPoint.X = tpPos[0]; this.TargetTeleportPoint.Y = tpPos[1]; this.TargetTeleportPoint.Z = tpPos[2]; this.TargetMarkerPoint.X = mrPos[0]; this.TargetMarkerPoint.Y = mrPos[1]; this.TargetMarkerPoint.Z = mrPos[2]; ok = true; break; } ratioNow -= ratioInc; } if (!ok) { this.TargetTeleportPoint.X = this.SourceMovePoint.X; this.TargetTeleportPoint.Y = this.SourceMovePoint.Y; this.TargetTeleportPoint.Z = this.SourceMovePoint.Z; this.TargetMarkerPoint.X = this.SourceMovePoint.X; this.TargetMarkerPoint.Y = this.SourceMovePoint.Y; this.TargetMarkerPoint.Z = this.SourceMovePoint.Z + this.Plugin.Settings.PlayerRadius; } } var mpos = this.Marker.LocalTransform.Position; mpos.X = this.TargetMarkerPoint.X; mpos.Y = this.TargetMarkerPoint.Y; mpos.Z = this.TargetMarkerPoint.Z; this.Marker.Update(totalTime); }
/// <summary> /// Retrieve Direct Children from this Node /// </summary> /// <param name="node"></param> /// <returns></returns> public static IEnumerable <NiAVObject> GetChildren(this NiNode node) { return(node.Children.Where(rf => rf.IsValid() && rf.Object != null).Select(rf => rf.Object)); }
private List <NiAVObject> GetHelmetNodes(NiNode root) { var ls = new List <NiAVObject>(); if (root != null) { bool hadHead = false; foreach (var ch in root.Children) { if (ch == null) { continue; } string nm = ch.Name.Text; if (string.IsNullOrEmpty(nm) || !nm.EndsWith("]")) { continue; } int ix = nm.LastIndexOf('('); if (ix < 0) { continue; } nm = nm.Substring(ix + 1); ix = nm.IndexOf(')'); if (ix < 0) { continue; } nm = nm.Substring(0, ix); uint formId = 0; if (!uint.TryParse(nm, System.Globalization.NumberStyles.HexNumber, null, out formId)) { continue; } var form = TESForm.LookupFormById(formId); if (form == null || form.FormType != FormTypes.Armor) { continue; } uint biped = NetScriptFramework.Memory.ReadUInt32(form.Address + 0x1B8); if ((biped & this.IsHelmetBipedMask) != 0 && (biped & this.NotHelmetBipedMask) == 0) { if ((biped & this.IsHeadBipedMask) != 0) { hadHead = true; } ls.Add(ch); } } this.HadHeadInHelmetNodes = hadHead; } return(ls); }
internal override void Apply() { this.NiNode_ctor = NetScriptFramework.Main.GameInfo.GetAddressOf(68936); _cachedOffsets = new int[256]; ulong vid = 17693; int baseOffset = 0x5430; Events.OnMainMenu.Register(e => { if (this._curPlaceNode == null) { var alloc = MemoryManager.Allocate(0x130, 0); Memory.InvokeCdecl(this.NiNode_ctor, alloc, 0); this._curPlaceNode = MemoryObject.FromAddress <NiNode>(alloc); this._curPlaceNode.IncRef(); alloc = MemoryManager.Allocate(0x10, 0); this._curPlacePos = MemoryObject.FromAddress <NiPoint3>(alloc); Memory.WriteZero(this._curPlacePos.Address, 0xC); } }, 0, 1); Memory.WriteHook(new HookParameters() { Address = NetScriptFramework.Main.GameInfo.GetAddressOf(vid, 0x5CF2 - baseOffset, 0, "0F B6 D9 0F BE C2"), IncludeLength = 6, ReplaceLength = 6, Before = ctx => { TESObjectWEAP weap = null; Actor actor = null; int count = ctx.CX.ToUInt8(); try { weap = MemoryObject.FromAddress <TESObjectWEAP>(ctx.R12); } catch { } try { actor = MemoryObject.FromAddress <Actor>(ctx.R15); } catch { } int now = count; _mod(weap, actor, ref now); if (now > 255) { now = 255; } if (now != count) { ctx.CX = new IntPtr(now); } }, }); Memory.WriteHook(new HookParameters() { Address = NetScriptFramework.Main.GameInfo.GetAddressOf(vid, 0x603D - baseOffset, 0, "E8"), IncludeLength = 5, ReplaceLength = 5, After = ctx => { TESObjectWEAP weap = null; Actor actor = null; int count = ctx.AX.ToUInt8(); try { weap = MemoryObject.FromAddress <TESObjectWEAP>(ctx.R12); } catch { } try { actor = MemoryObject.FromAddress <Actor>(ctx.R15); } catch { } int now = count; _mod(weap, actor, ref now); if (now > 255) { now = 255; } if (now != count) { ctx.AX = new IntPtr(now); } }, }); Memory.WriteHook(new HookParameters() { Address = NetScriptFramework.Main.GameInfo.GetAddressOf(42928, 0xB91B - 0xB360, 0, "E8"), IncludeLength = 5, ReplaceLength = 5, After = ctx => { if (settings.ForceDrawTime.Value >= 0.0) { ctx.XMM0f = (float)settings.ForceDrawTime.Value; } else { int track = _projTrack; if (track > 0) { track--; _projTrack = track; if (_projStrength.HasValue) { ctx.XMM0f = _projStrength.Value; if (track == 0) { _projStrength = null; } } else { _projStrength = ctx.XMM0f; } } } }, }); Memory.WriteHook(new HookParameters() { Address = NetScriptFramework.Main.GameInfo.GetAddressOf(vid, 0x621C - baseOffset, 0, "F3 0F 10 44 24 48"), IncludeLength = 0, //0x3D - 0x1C, ReplaceLength = 0x3D - 0x1C, Before = ctx => { var pos = MemoryObject.FromAddress <NiPoint3>(ctx.BP + 0x68); int index = ctx.SI.ToUInt8(); if (index <= 1) { pos.X = Memory.ReadFloat(ctx.SP + 0x48); pos.Y = Memory.ReadFloat(ctx.SP + 0x4C); pos.Z = Memory.ReadFloat(ctx.SP + 0x50); return; } var plr = PlayerCharacter.Instance; bool isPlayer = plr != null && plr.Cast <PlayerCharacter>() == ctx.R15; if (isPlayer) { _projTrack = index; } else { _projTrack = 0; } float x = 0.0f; float y = 0.0f; _calculate_projectile_offset(index - 1, ref x, ref y); if (this._curPlaceHadNode) { var npos = this._curPlaceNode.WorldTransform.Position; npos.X = Memory.ReadFloat(ctx.SP + 0x48); npos.Y = Memory.ReadFloat(ctx.SP + 0x4C); npos.Z = Memory.ReadFloat(ctx.SP + 0x50); this._curPlacePos.X = x; this._curPlacePos.Y = 0.0f; this._curPlacePos.Z = y; this._curPlaceNode.WorldTransform.Translate(this._curPlacePos, npos); pos.X = npos.X; pos.Y = npos.Y; pos.Z = npos.Z; } else { bool didGet = false; if (isPlayer) { var pcam = PlayerCamera.Instance; if (pcam != null) { var pnode = pcam.Node; if (pnode != null) { byte[] buf = Memory.ReadBytes(pnode.WorldTransform.Address, 0x34); Memory.WriteBytes(this._curPlaceNode.WorldTransform.Address, buf); var tpos = this._curPlaceNode.WorldTransform.Position; tpos.X = Memory.ReadFloat(ctx.SP + 0x48); tpos.Y = Memory.ReadFloat(ctx.SP + 0x4C); tpos.Z = Memory.ReadFloat(ctx.SP + 0x50); this._curPlacePos.X = x; this._curPlacePos.Y = 0.0f; this._curPlacePos.Z = y; this._curPlaceNode.WorldTransform.Translate(this._curPlacePos, pos); didGet = true; } } } if (!didGet) { pos.X = Memory.ReadFloat(ctx.SP + 0x48) + x; pos.Y = Memory.ReadFloat(ctx.SP + 0x4C); pos.Z = Memory.ReadFloat(ctx.SP + 0x50) + y; } } } }); Events.OnWeaponFireProjectilePosition.Register(e => { if (e.Node != null) { byte[] buf = Memory.ReadBytes(e.Node.WorldTransform.Address, 0x34); Memory.WriteBytes(this._curPlaceNode.WorldTransform.Address, buf); this._curPlaceHadNode = true; } else { this._curPlaceHadNode = false; } }, 50); }
private void FillValidBipedObjects(NiNode root, List <NiAVObject> ls) { this.ExploreEquipment(root, root, ls); }