示例#1
0
        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);
                        }
                    }
                }
            }
        }
示例#2
0
        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);
        }
示例#3
0
        /// <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());
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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;
                }
            }
        }
示例#9
0
        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();
                }
            }
        }
示例#10
0
    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);
    }
示例#11
0
        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);
            }
        }
示例#12
0
        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);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#16
0
        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);
                    }
                }
            }
        }
示例#17
0
        /// <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;
        }
示例#18
0
        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);
            }
        }
示例#19
0
        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);
        }
示例#20
0
 /// <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));
 }
示例#21
0
        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);
 }