csharp/ACEmulator/ACE/Source/ACE.Server/Physics/SpherePath.cs

SpherePath.cs
using System;
using System.Collections.Generic;
using System.Numerics;
using ACE.Server.Physics.Common;

namespace ACE.Server.Physics.Animation
{
    public enum InsertType
    {
        Transition = 0x0,
        Placement = 0x1,
        InitialPlacement = 0x2,
    };
    public clast SpherePath
    {
        public int NumSphere;                       // 0
        public List LocalSphere;            // 4
        public Vector3 LocalLowPoint;               // 8
        public List GlobalSphere;           // 12
        public Vector3 GlobalLowPoint;              // 16
        public List LocalSpaceSphere;       // 20
        public Vector3 LocalSpaceLowPoint;          // 24
        public List LocalSpaceCurrCenter;   // 28
        public List GlobalCurrCenter;       // 32
        public Position LocalSpacePos;              // 36
        public Vector3 LocalSpaceZ;                 // 40
        public ObjCell BeginCell;                   // 44
        public Position BeginPos;                   // 48
        public Position EndPos;                     // 52
        public ObjCell CurCell;                     // 56 
        public Position CurPos;                     // 60
        public Vector3 GlobalOffset;                // 64
        public bool StepUp;                         // 68
        public Vector3 StepUpNormal;                // 69
        public bool Collide;                        // 73
        public ObjCell CheckCell;                   // 77
        public Position CheckPos;                   // 81
        public InsertType InsertType;               // 85
        public bool StepDown;                       // 89
        public InsertType Backup;                   // 90
        public ObjCell BackupCell;                  // 94
        public Position BackupCheckPos;             // 98
        public bool ObstructionEthereal;            // 102
        public bool HitsInteriorCell;               // 103
        public bool BuildingCheck;                  // 104
        public float WalkableAllowance;             // 105
        public float WalkInterp;                    // 111 *
        public float StepDownAmt;                   // 107
        public Sphere WalkableCheckPos;             // 111
        public Polygon Walkable;                    // 115
        public bool CheckWalkable;                  // 119
        public Vector3 WalkableUp;                  // 120
        public Position WalkablePos;                // 124
        public float WalkableScale;                 // 128
        public bool CellArrayValid;                 // 132
        public bool NegStepUp;                      // 133
        public Vector3 NegCollisionNormal;          // 134
        public bool NegPolyHit;                     // 138
        public bool PlacementAllowsSliding;         // 139

        public SpherePath()
        {
            LocalSpacePos = new Position();
            CurPos = new Position();
            CheckPos = new Position();
            BackupCheckPos = new Position();
            WalkableCheckPos = new Sphere();
            //NumSphere = 2;

            LocalSphere = new List();
            GlobalSphere = new List();
            LocalSpaceSphere = new List();

            LocalSpaceCurrCenter = new List();
            GlobalCurrCenter = new List();

            Init();
        }

        public void Init()
        {
            PlacementAllowsSliding = true;
        }

        public void InitPath(ObjCell beginCell, Position beginPos, Position endPos)
        {
            BeginPos = beginPos;
            BeginCell = beginCell;
            EndPos = endPos;

            if (beginPos != null)
            {
                InsertType = InsertType.Transition;
                CurPos = new Position(beginPos);
            }
            else
            {
                InsertType = InsertType.Placement;
                CurPos = new Position(endPos);
            }

            CurCell = beginCell;
            CacheGlobalCurrCenter();
        }

        public void InitSphere(int numSphere, List spheres, float scale)
        {
            if (numSphere  WalkableAllowance;
        }

        public TransitionState PrecipiceSlide(Transition transition)
        {
            var collisions = transition.CollisionInfo;
            Vector3 collisionNormal = Vector3.Zero;
            var found = Walkable.find_crossed_edge(WalkableCheckPos, WalkableUp, ref collisionNormal);

            if (!found)
            {
                Walkable = null;
                return TransitionState.Collided;
            }

            Walkable = null;
            StepUp = false;
            collisionNormal = WalkablePos.Frame.LocalToGlobalVec(collisionNormal);

            var blockOffset = LandDefs.GetBlockOffset(CurPos.ObjCellID, CheckPos.ObjCellID);
            var offset = GlobalSphere[0].Center - GlobalCurrCenter[0].Center + blockOffset;

            if (Vector3.Dot(collisionNormal, offset) > 0.0f)
                collisionNormal *= -1.0f;

            return GlobalSphere[0].SlideSphere(transition, ref collisionNormal, GlobalCurrCenter[0].Center);
        }

        public void RestoreCheckPos()
        {
            CheckPos = new Position(BackupCheckPos);
            CheckCell = BackupCell;
            CellArrayValid = false;
            CacheGlobalSphere(null);
        }

        public void SaveCheckPos()
        {
            BackupCell = CheckCell;
            BackupCheckPos = new Position(CheckPos);
        }

        public void SetCheckPos(Position position, ObjCell cell)
        {
            CheckPos = new Position(position);
            CheckCell = cell;
            CellArrayValid = false;
            CacheGlobalSphere(null);
        }

        public void SetCollide(Vector3 collisionNormal)
        {
            Collide = true;
            BackupCell = CheckCell;
            BackupCheckPos = new Position(CheckPos);
            StepUpNormal = new Vector3(collisionNormal.X, collisionNormal.Y, collisionNormal.Z);
            WalkInterp = 1.0f;
        }

        public void SetNegPolyHit(bool stepUp, Vector3 collisionNormal)
        {
            NegStepUp = stepUp;
            NegPolyHit = true;
            NegCollisionNormal = -collisionNormal;
        }

        public void SetWalkable(Sphere sphere, Polygon poly, Vector3 zAxis, Position localPos, float scale)
        {
            WalkableCheckPos = new Sphere(sphere);
            Walkable = poly;
            WalkableUp = zAxis;
            WalkablePos = new Position(localPos);
            WalkableScale = scale;
        }

        public void SetWalkableCheckPos(Sphere sphere)
        {
            WalkableCheckPos = new Sphere(sphere);
        }

        public TransitionState StepUpSlide(Transition transition)
        {
            var collisions = transition.CollisionInfo;

            collisions.ContactPlaneValid = false;
            collisions.ContactPlaneIsWater = false;

            return GlobalSphere[0].SlideSphere(transition, ref StepUpNormal, GlobalCurrCenter[0].Center);
        }
    }
}