예제 #1
0
        void DoInCup()
        {
            ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);

            if (Utilities.IsValid(cup))
            {
                //if ball is not in cup teleport ball in cup
                Collider c = cup.colliderForThrow;
                c.enabled = true;
                Vector3 cPoint = c.ClosestPoint(transform.position);
                c.enabled = false;
                Bounds b = cup.GetBounds();
                b.size = b.size += Vector3.up;
                if (Vector3.Distance(cPoint, transform.position) > 0.01f && ((_rigidbody.velocity.sqrMagnitude == 0) || (b.Contains(transform.position) == false)))
                {
                    //Debug.Log($"cPoint: {cPoint.ToString("F3")} point: {transform.position.ToString("F3")}");
                    //Debug.Log($"[ThryBP] Teleported ball into cup ({state[1]},{state[2]},{state[3]})");
                    transform.position = cup.GetBounds().center;
                }
                else if (Networking.IsOwner(gameObject))
                {
                    if (_mainScript.gamemode == 0)
                    {
                        if (Time.time - stateStartTime > (autoRespawnBallAfterCupHit ? 2 : 20))
                        {
                            _mainScript.CountCupHit(state[1], state[2], state[3], currentPlayer, state[0] == STATE_RIMING ? 1 : 0);
                            _mainScript.RemoveCup(state[1], state[2], state[3], currentPlayer);
                            Respawn();
                        }
                    }
                    else if (_mainScript.gamemode == 1)
                    {
                        if (Time.time - stateStartTime > 1)
                        {
                            _mainScript.CountCupHit(state[1], state[2], state[3], currentPlayer, state[0] == STATE_RIMING ? 1 : 0);
                            _mainScript.RemoveCup(state[1], state[2], state[3], currentPlayer);
                            Respawn();
                        }
                    }
                    else if (_mainScript.gamemode == 2)
                    {
                        if (Time.time - stateStartTime > 3)
                        {
                            _mainScript.CountCupHit(state[1], state[2], state[3], currentPlayer, state[0] == STATE_RIMING ? 1 : 0);
                            Respawn();
                        }
                    }
                }
            }
        }
예제 #2
0
        private Vector3 OptimalVectorChangeAngle(Vector3 velocity, Vector3 position, float tableHeight, ThryBP_Glass aimedCup)
        {
            //Calculate trajectory to that cup
            Vector3 horizonzalDistance = aimedCup.transform.position - position;

            horizonzalDistance.y = 0;
            //https://www.youtube.com/watch?v=bqYtNrhdDAY&ab_channel=MichelvanBiezen
            //https://www.youtube.com/watch?v=pQ23Eb-bXvQ&ab_channel=MichelvanBiezen
            float g     = -Physics.gravity.y;
            float v2    = velocity.sqrMagnitude;
            float x     = horizonzalDistance.magnitude;
            float h     = position.y - (tableHeight + aimedCup.GetBounds().size.y);
            float phi   = Mathf.Atan(x / h);
            float theta = (Mathf.Acos(((g * x * x / v2) - h) / Mathf.Sqrt(h * h + x * x)) + phi) / 2;

            Vector3 newVel = (horizonzalDistance.normalized * Mathf.Cos(theta) + Vector3.up * Mathf.Sin(theta)) * velocity.magnitude;

            if (float.IsNaN(theta))
            {
                //cant reacht cup with current velocity
                //just aim in it's direction instead
                Vector3 horizontalVel = velocity;
                horizontalVel.y = 0;
                newVel          = horizonzalDistance.normalized * horizontalVel.magnitude;
                newVel.y        = velocity.y;
            }
            return(newVel);
        }
예제 #3
0
        private Vector3 OptimalVectorChangeStrength(Vector3 velocity, Vector3 position, ThryBP_Glass cup)
        {
            Vector3 cupOpening       = cup.transform.position + Vector3.up * cup.GetBounds().size.y;
            Vector3 horizonzalVector = cupOpening - position;

            horizonzalVector.y = 0;
            Vector3 horizonzalVelocity = velocity;

            horizonzalVelocity.y = 0;
            //https://www.youtube.com/watch?v=mOYJKv22qeQ&list=PLX2gX-ftPVXUUlf-9Eo_6ut4kP6wKaSWh&index=7&ab_channel=MichelvanBiezen
            // d = v0 * cos(w) * t
            // => t = d / (v0 * cos(w))
            // y = y0 + v0 * sin(w) * t - 0.5 * g * t2
            // y = y0 + v0 * sin(w) * ( d / (v0 * cos(w)) ) - 0.5 * g * ( d / (v0 * cos(w)) )2
            // y = y0 + tan(w) * d - 0.5 * g * ( d / (v0 * cos(w)) )2
            // y0 - y + tan(w) * d = 0.5 * g * ( d / (v0 * cos(w)) )2
            // 2(y0 - y + tan(w) * d) / g = ( d / (v0 * cos(w)) )2
            // sqrt( 2(y0 - y + tan(w) * d) / g) = d / (v0 * cos(w))
            // v0 * cos(w) = d / sqrt( 2(y0 - y + tan(w) * d) / g)
            // v0 = d / sqrt( 2(y0 - y + tan(w) * d) / g) / cos(w)
            float d  = horizonzalVector.magnitude;
            float y0 = position.y;
            float y  = cupOpening.y;
            float w  = Mathf.Deg2Rad * Vector3.Angle(horizonzalVelocity, velocity);
            float g  = -Physics.gravity.y;

            float v0 = d / Mathf.Sqrt(2 * (y0 - y + Mathf.Tan(w) * d) / g) / Mathf.Cos(w);

            Vector3 newDirection = horizonzalVector.normalized * horizonzalVelocity.magnitude;

            newDirection.y = velocity.y;

            return(newDirection.normalized * v0);
        }
예제 #4
0
        private Vector3 DoAIVectoring(Vector3 velocity, Vector3 position, float skill)
        {
            if (skill == 0)
            {
                return(velocity);
            }
            //Get Point where ball will hit table
            Vector3      predictionTableHit = PredictTableHit(velocity, position, tableHeight);
            ThryBP_Glass cup = GetClosestGlassToPredictedTableCollision(predictionTableHit);

            if (cup == null)
            {
                return(velocity);
            }
            Vector3 cupOpening    = cup.transform.position + Vector3.up * cup.GetBounds().size.y;
            Vector3 optimalVector = OptimalVectorChangeStrength(velocity, position, cup);

            float lerping = Random.Range(0f, 1f);

            if (lerping < skill)
            {
                lerping = 1;
            }
            velocity = Vector3.Lerp(velocity, optimalVector, lerping);

            return(velocity);
        }
예제 #5
0
        void DoRimming()
        {
            if (rimming < RIMMING_TOTAL_AGULAR_ROTATION)
            {
                ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);
                if (Utilities.IsValid(cup))
                {
                    rimming += RIMMING_SPEED * Time.deltaTime;

                    float inside    = 0.9f - rimming / RIMMING_TOTAL_AGULAR_ROTATION * 0.15f;
                    float downwards = 1 - rimming / RIMMING_TOTAL_AGULAR_ROTATION * 0.3f;
                    float angle     = (rimming - Mathf.Pow(rimming * 0.009f, 2)) / cup.circumfrence * 0.4f;
                    transform.position = cup.transform.position + Vector3.up * (cup.GetBounds().size.y *downwards)
                                         + Quaternion.Euler(0, angle, 0) * Vector3.forward * (cup.radius * cup.transform.lossyScale.x * inside - _radius);
                }
            }
            else
            {
                ThryBP_Glass cup = _mainScript.GetCup(state[1], state[2], state[3]);
                if (Utilities.IsValid(cup))
                {
                    cup.colliderInside.SetActive(true);
                    cup.colliderForThrow.enabled = false;
                    _rigidbody.velocity          = Quaternion.Euler(0, 90 + rimming, 0) * Vector3.forward * 0.3f;  //in circle
                    _rigidbody.velocity         += Quaternion.Euler(0, rimming + 180, 0) * Vector3.forward * 0.1f; //inwards
                    _rigidbody.velocity         += Vector3.down * 0.1f;                                            //downwards
                    SetDynamic();
                    localState     = STATE_IN_CUP;
                    stateStartTime = Time.time;
                    _TriggerSplash();
                    _pickup.pickupable = !autoRespawnBallAfterCupHit;
                }
            }
        }
예제 #6
0
        private void BallGlassCollision(Collision collision, ThryBP_Glass hitGlass)
        {
            Bounds b = hitGlass.GetBounds();
            bool   isCollisionOnTop = (b.max.y < transform.position.y);

            SetDynamic();

            if (isCollisionOnTop)
            {
                Vector3 p1 = transform.position;
                p1.y = 0;
                Vector3 p2 = hitGlass.transform.position;
                p2.y = 0;
                float distanceFromCenter = Vector3.Distance(p1, p2) / ((b.extents.x + b.extents.z) / 2);

                if (distanceFromCenter < COLLISION_MAXIMUM_DISTANCE_FROM_CENTER)
                {
                    float angle = Vector3.Angle(_lastvelocies[_lastvelociesHead], Vector3.down);
                    //bool tripOnEdge = distanceFromCenter > Random.Range(0, 0.85f);
                    bool tripOnEdge = distanceFromCenter > Random.Range(0.4f, 0.7f) && angle > Random.Range(45, 80); //if it lands really flat chances are higher for it to ride edge

                    if (tripOnEdge)
                    {
                        SetState(STATE_RIMING);
                        state[1] = (byte)hitGlass.player.playerIndex;
                        state[2] = (byte)hitGlass.row;
                        state[3] = (byte)hitGlass.collum;
                        rimming  = Vector3.Angle(hitGlass.transform.rotation * Vector3.forward, p2 - p1);
                        if ((p2 - p1).x > 0)
                        {
                            rimming = 360 - rimming;
                        }
                        rimming  = rimming % 360;
                        state[4] = (byte)(rimming / 2);
                        state[5] = (byte)(distanceFromCenter * 100);
                    }
                    else
                    {
                        hitGlass.colliderForThrow.enabled = false;
                        hitGlass.colliderInside.SetActive(true);
                        _pickup.pickupable = !autoRespawnBallAfterCupHit;
                        SetState(STATE_IN_CUP);
                        state[1] = (byte)hitGlass.player.playerIndex;
                        state[2] = (byte)hitGlass.row;
                        state[3] = (byte)hitGlass.collum;

                        _TriggerSplash();
                        _rigidbody.velocity = Vector3.down * startVelocityLocal.magnitude;
                    }
                    RequestSerialization();
                }
            }
        }
예제 #7
0
        private Vector3 DoAimbotVectoring(Vector3 velocity, Vector3 position, float strength)
        {
            if (strength == 0)
            {
                return(velocity);
            }
            //Get Point where ball will hit table
            Vector3      predictionTableHit = PredictTableHit(velocity, position, tableHeight);
            ThryBP_Glass cup = GetClosestGlassToPredictedTableCollision(predictionTableHit);

            if (cup == null)
            {
                return(velocity);
            }
            Vector3 cupOpening    = cup.transform.position + Vector3.up * cup.GetBounds().size.y;
            Vector3 hitOnCupPlane = PredictTableHit(velocity, position, cupOpening.y);

            if (Vector3.Distance(cupOpening, hitOnCupPlane) > strength)
            {
                return(velocity);
            }
            return(OptimalVectorChangeStrength(velocity, position, cup));
        }
예제 #8
0
 public float GetHeight()
 {
     return(glass.GetBounds().size.y);
 }