コード例 #1
0
        public bool ConditionMatched(ModuleBlockMover block, bool localInput, float m_Val, float m_Vel)
        {
            bool Invert = m_InputParam < 0;

            switch (m_InputType)
            {
            case InputType.AlwaysOn:
                return(true);

            case InputType.OnPress:
                m_InputParam = Mathf.Sign(m_InputParam);
                return((KeyState(CanInput(block, localInput)) == 1) != Invert);

            case InputType.OnRelease:
                m_InputParam = Mathf.Sign(m_InputParam);
                return((KeyState(CanInput(block, localInput)) == 3) != Invert);

            case InputType.WhileHeld:
                m_InputParam = Mathf.Sign(m_InputParam);
                return((KeyState(CanInput(block, localInput)) != 0) != Invert);

            case InputType.Toggle:
                m_InputParam = Mathf.Sign(m_InputParam - 0.001f);
                if (KeyState(CanInput(block, localInput)) == 1)
                {
                    m_InputParam = -m_InputParam;
                }
                return(m_InputParam > 0);

            case InputType.EnemyTechIsNear:
                Visible target = block.GetTarget();
                if (target == null)
                {
                    return(Invert);
                }
                return(((target.centrePosition - block.block.centreOfMassWorld).sqrMagnitude < m_InputParam * m_InputParam) != Invert);

            case InputType.PlayerTechIsNear:
                if (Singleton.playerTank == null)
                {
                    return(Invert);
                }
                if (Singleton.playerTank == block.block.tank)
                {
                    return(!Invert);
                }
                return(((Singleton.playerTank.visible.centrePosition - block.block.centreOfMassWorld).sqrMagnitude < m_InputParam * m_InputParam) != Invert);

            case InputType.AboveSurfaceElev:
                var comw = block.block.centreOfMassWorld;
                ManWorld.inst.GetTerrainHeight(comw, out float outHeight);
                return((comw.y > outHeight + m_InputParam) != Invert);

            case InputType.AboveVelocity:
                return((block.block.tank.rbody.GetPointVelocity(block.block.centreOfMassWorld).sqrMagnitude > m_InputParam * m_InputParam) != Invert);

            case InputType.IfPosAbove:
                if (block.IsPlanarVALUE)
                {
                    return(((block.PVALUE + 900) % 360) - 180 > m_InputParam);
                }
                m_InputParam = Mathf.Max(m_InputParam, 0f);
                return(block.PVALUE > m_InputParam);

            case InputType.IfPosBelow:
                if (block.IsPlanarVALUE)
                {
                    return(((block.PVALUE + 900) % 360) - 180 < m_InputParam);
                }
                m_InputParam = Mathf.Max(m_InputParam, 0f);
                return(block.PVALUE < m_InputParam);

            case InputType.IfPosEqual:
                if (block.IsPlanarVALUE)
                {
                    return(m_InputParam.Approximately(((block.PVALUE + 900) % 360) - 180));
                }
                m_InputParam = Mathf.Max(m_InputParam, 0f);
                return(block.PVALUE.Approximately(m_InputParam));

            case InputType.IfSpeedAbove:
                return(m_Vel > m_InputParam);

            case InputType.IfSpeedBelow:
                return(m_Vel < m_InputParam);

            case InputType.IfSpeedEqual:
                return(m_Vel.Approximately(m_InputParam));

            default:
                return(false);
            }
        }
コード例 #2
0
        /// <summary>
        /// Process this operation, checking if it's active and then modifying values based on its function
        /// </summary>
        /// <param name="block">The ModuleBlockMover to use for calculations</param>
        /// <param name="ProjectDirToPlane">Is the value used on a plane, or on an axis</param>
        /// <param name="Value">Positional value to modify</param>
        /// <param name="Velocity">Positional velocity to modify</param>
        /// <param name="FreeJoint">Allow free-moving in the attached body</param>
        /// <param name="LockJoint">Ghost-phasing</param>
        /// <returns>Returns true if satisfied</returns>
        public bool Calculate(ModuleBlockMover blockMover, bool LocalInput, bool ProjectDirToPlane, ref float Value, ref float Velocity, ref ModuleBlockMover.MoverType moverType, out int Skip)
        {
            Skip = 0;
            switch (m_OperationType)
            {
            case OperationType.OrThen: return(false);

            case OperationType.ElseThen: Skip = 1; return(false);

            default: break;
            }
            TankBlock block = blockMover.block;

            if (ConditionMatched(blockMover, LocalInput, Value, Velocity))
            {
                switch (m_OperationType)
                {
                case OperationType.ShiftPos:
                    Value += m_Strength;
                    return(true);

                case OperationType.SetPos:
                    Value = m_Strength;
                    return(true);

                case OperationType.ShiftSpeed:
                    Velocity += m_Strength;
                    return(true);

                case OperationType.SetSpeed:
                    Velocity = m_Strength;
                    return(true);

                case OperationType.ArrowPoint:
                    var vel = block.tank.rbody.GetPointVelocity(block.centreOfMassWorld);
                    if (blockMover.IsPlanarVALUE)
                    {
                        var planar = Vector3.ProjectOnPlane(vel * Mathf.Sign(m_Strength), block.trans.up);
                        Value += SafePlanarPointAngle(block.trans, planar, Value) * Mathf.Clamp01(m_Strength * m_Strength * planar.magnitude);
                        return(true);
                    }
                    Value += block.trans.InverseTransformDirection(vel * Mathf.Sign(m_Strength)).y *Mathf.Clamp01(m_Strength * m_Strength);
                    return(true);

                case OperationType.TargetPoint:
                    Visible target = blockMover.GetTarget();
                    if (target == null)
                    {
                        if (m_ResetTimer)
                        {
                            Value        = blockMover.UseLIMIT ? blockMover._CENTERLIMIT : 0f;
                            m_ResetTimer = false;
                        }
                        return(false);
                    }
                    m_ResetTimer = true;
                    Value       += PointAtTarget(block.trans, (target.GetAimPoint(block.trans.position) - block.centreOfMassWorld) * Mathf.Sign(m_Strength), ProjectDirToPlane, Value) * m_Strength * m_Strength;// * Mathf.Abs(m_Strength);
                    return(true);

                case OperationType.TargetPointPredictive:
                    float muzzleVelocity = Mathf.Abs(m_Strength);
                    bool  useGravity     = m_Strength > 0;

                    Visible targetPred = blockMover.GetTarget();

                    if (targetPred == null)
                    {
                        if (m_ResetTimer)
                        {
                            Value        = blockMover.UseLIMIT ? blockMover._CENTERLIMIT : 0f;
                            m_ResetTimer = false;
                        }
                        return(false);
                    }

                    Vector3 BlockCenter    = block.centreOfMassWorld;
                    Vector3 AimPointVector = targetPred.GetAimPoint(BlockCenter);
                    Vector3 vector         = AimPointVector - BlockCenter;
                    if (muzzleVelocity > 0f)
                    {
                        Vector3   dist             = vector;
                        Rigidbody rbodyTank        = block.tank.rbody;
                        Vector3   angularToggle    = rbodyTank.angularVelocity;
                        Vector3   relativeVelocity = targetPred.rbody.velocity - (rbodyTank.velocity + angularToggle);

                        float time = dist.magnitude / muzzleVelocity;

                        Vector3 relativeAcceleration = BallisticTargeting.GetAcceleration(targetPred.tank) - BallisticTargeting.GetAcceleration(block.tank);

                        if (useGravity)
                        {
                            relativeAcceleration -= Physics.gravity;
                        }

                        float exactTime = BallisticTargeting.SolveBallisticArc(BlockCenter, muzzleVelocity, AimPointVector, relativeVelocity, relativeAcceleration);
                        if (exactTime != Mathf.Infinity)
                        {
                            time = exactTime;
                        }

                        // vector now represents where the enemy will be - still need elevation
                        vector += (time * relativeVelocity) + (relativeAcceleration * time * time / 2);
                    }

                    m_ResetTimer = true;
                    Value       += PointAtTarget(block.trans, vector, ProjectDirToPlane, Value);// * Mathf.Abs(m_Strength);
                    return(true);

                case OperationType.PlayerPoint:
                    Tank playerTank = Singleton.playerTank;
                    if (playerTank == null)
                    {
                        return(false);
                    }
                    Value += PointAtTarget(block.trans, (playerTank.WorldCenterOfMass - block.centreOfMassWorld) * Mathf.Sign(m_Strength), ProjectDirToPlane, Value) * m_Strength * m_Strength;    // * Mathf.Abs(m_Strength);
                    return(true);

                case OperationType.GroundPoint:
                    var comw = block.centreOfMassWorld;
                    ManWorld.inst.GetTerrainHeight(comw, out float outHeight);
                    //return (comw.y > outHeight + m_InputParam);
                    float reducer = Mathf.Abs(Vector3.Dot(block.trans.up, Vector3.up));
                    if (blockMover.IsPlanarVALUE)
                    {
                        reducer = 1f - reducer;
                    }
                    Value += PointAtTarget(block.trans, Vector3.up * (outHeight - comw.y) * Mathf.Sign(m_Strength), ProjectDirToPlane, Value) * m_Strength * m_Strength * reducer;
                    //Value += PointAtTarget(block.trans, Vector3.down * Mathf.Sign(m_Strength), ProjectDirToPlane, Value) * m_Strength * m_Strength;// * Mathf.Abs(m_Strength);
                    return(true);

                case OperationType.NorthPoint:

                    if (blockMover.IsPlanarVALUE)
                    {
                        Value = (Vector3.SignedAngle(block.trans.forward, Vector3.ProjectOnPlane(Vector3.forward, block.trans.up), block.trans.up) + m_Strength + 900f) % 360f - 180f;
                    }
                    else
                    {
                        float rad = m_Strength * Mathf.Deg2Rad;
                        Value = block.trans.InverseTransformDirection(new Vector3(Mathf.Sin(rad), 0f, Mathf.Cos(rad))).y;
                    }
                    return(true);

                case OperationType.SetFreeJoint:
                    if (blockMover.CanOnlyBeLockJoint)
                    {
                        return(false);
                    }
                    if (blockMover.CannotBeFreeJoint)
                    {
                        moverType = ModuleBlockMover.MoverType.Dynamic;
                    }
                    else
                    {
                        moverType = ModuleBlockMover.MoverType.Physics;
                    }
                    return(true);

                case OperationType.SetBodyJoint:
                    if (blockMover.CanOnlyBeLockJoint)
                    {
                        return(false);
                    }
                    moverType = ModuleBlockMover.MoverType.Dynamic;
                    return(true);

                case OperationType.SetLockJoint:
                    if (blockMover.CanOnlyBeLockJoint)
                    {
                        return(false);
                    }
                    moverType = ModuleBlockMover.MoverType.Static;
                    return(true);

                case OperationType.CameraPoint:
                    var camTr = Singleton.cameraTrans;
                    if (camTr == null)
                    {
                        return(false);
                    }
                    Value += PointAtTarget(block.trans, camTr.forward * Mathf.Sign(m_Strength), ProjectDirToPlane, Value) * m_Strength * m_Strength;    // * Mathf.Abs(m_Strength);
                    return(true);

                case OperationType.IfThen:
                    if (m_ResetTimer)
                    {
                        m_InternalTimer = 0f;
                        m_ResetTimer    = false;
                    }
                    if (m_Strength == 0f)
                    {
                        return(true);
                    }

                    m_InternalTimer += Time.fixedDeltaTime;
                    // If time is satisfied and strength is positive, do not skip. Negative strength will only activate within that timeframe
                    bool met = (m_InternalTimer >= Mathf.Abs(m_Strength)) == (m_Strength >= 0f);
                    Skip = met ? 0 : 1;
                    return(met);

                case OperationType.CursorPoint:
                    Value += PointAtTarget(block.trans, (AdjustAttachPosition.PointerPos - block.centreOfMassWorld) * Mathf.Sign(m_Strength), ProjectDirToPlane, Value) * m_Strength * m_Strength;    // * Mathf.Abs(m_Strength);
                    return(true);

                case OperationType.Nothing:
                    return(true);    // Light it up in the GUI. Technically, the task did not fail

                case OperationType.FireWeapons:
                    if (blockMover.Holder == null)
                    {
                        return(false);
                    }
                    if (m_Strength < 0)
                    {
                        blockMover.Holder.ForceNoFireNextFrame = true;
                    }
                    else
                    {
                        blockMover.Holder.ForceFireNextFrame = true;
                    }
                    return(true);

                default:
                    return(false);
                }
            }
            else if (m_OperationType == OperationType.IfThen)
            {
                if (m_Strength != 0)
                {
                    m_InternalTimer += Time.fixedDeltaTime;
                }
                if (m_ResetTimer)
                {
                    m_InternalTimer = 0f;
                }
                else
                {
                    m_ResetTimer = true;
                }
                Skip = 1;
            }
            return(false);
        }