Example #1
0
    // Update is called once per frame
    protected override void Update()
    {
        base.Update();

        var currDirection   = Direction;
        var directionVector = currDirection.ToVector2();
        var endpoint        = transform.position.xy();

        //Swap prev points with current endpoints
        SwapPoints();
        //Clear the endpoint and offset list
        endpointSize = 0;
        offsetSize   = 0;
        //Init
        AddPoint(endpoint);
        AddOffset(-1);

        var movement = Time.deltaTime * LaserSpeed;

        bool gorillaTape = true;

        bool isMirror = false;

        // Set max iteration 20 to avoid infinite reflection
        for (var endpointIndex = 1; endpointIndex < MaxEndpoints; endpointIndex++)
        {
            var hit = Physics2D.Raycast(endpoint + directionVector, directionVector, 100);              //TODO: change 100 to max level width
            //Debug.Log(endpointIndex);
            DebugExt.Assert(hit.collider != null);
            if (hit.collider == null)
            {
                break; // for robustness
            }
            string hitName = hit.collider.name;
            isMirror = hitName.StartsWith("Mirror");

            var tPos = hit.collider.transform.position;

            if (directionVector.x.IsZero())
            {
                //Adjust the hit point when hitting from below
                if (directionVector.y > 0 && !isMirror)
                {
                    float offset = 0;
                    float dist;

                    if (hitName.StartsWith("Wall"))
                    {
                        offset = wallOffset;
                    }
                    else if (hitName.StartsWith("Gate"))
                    {
                        offset = gateOffset;
                    }
                    else if (hitName.StartsWith("Door"))
                    {
                        offset = doorOffset;
                    }
                    else if (hitName.StartsWith("Lever"))
                    {
                        offset = leverOffset;
                    }
                    else if (hitName.StartsWith("Trolley"))
                    {
                        offset = trolleyOffset;
                    }
                    else if (hitName.StartsWith("LaserEmitter"))
                    {
                        if (hit.collider.gameObject.GetComponent <LaserEmitter>().direction != Direction.Down)
                        {
                            offset = turretOffset;
                        }
                    }
                    else
                    {
                        offset = otherOffset;
                    }

                    //Fixes issue for when object is too close to the laser
                    //This assumes the object's collider is 1 unit high
                    if ((dist = tPos.y - endpoint.y) < 1.5f)
                    {
                        offset -= 1.5f - dist;
                    }

                    endpoint.y = hit.point.y + offset;

                    //gorillaTape = hit.point;
                }
                else
                {
                    endpoint.y = hit.collider.transform.position.y;
                    //Debug.Log("whoop-di-doo");
                }
            }
            else
            {
                endpoint.x = hit.collider.transform.position.x;
            }

            Vector2?previousEndpoint = null;

            if (endpointIndex >= prevSize)
            {
                previousEndpoint = endpoints[endpointIndex - 1];
            }
            else if (!endpoint.Equals(prevPoints[endpointIndex]))
            {
                previousEndpoint = prevPoints[endpointIndex];
                var previousDirection = previousEndpoint.Value - prevPoints[endpointIndex - 1];
                previousDirection.Normalize();
                if (directionVector != previousDirection)
                {
                    previousEndpoint = endpoints[endpointIndex - 1];
                }
            }

            if (previousEndpoint.HasValue)
            {
                var newEndpoint = previousEndpoint.Value + movement * directionVector;

                var diff = Vector2.Dot(endpoint - newEndpoint, directionVector);

                if (diff > 0)
                {
                    AddPoint(newEndpoint);
                    break;
                }
                movement += diff;
            }


            AddPoint(endpoint);


            if (hit.transform.tag == "Player")
            {
                var player = hit.transform.GetComponent <PlayerController>();

                if (player.IsAlive)
                {
                    player.Die();

                    AudioManager.PlaySFX("Laser Hit");
                }

                break;
            }
            else if (isMirror)
            {
                var mirror = hit.collider.GetComponent <Mirror>();
                if (mirror != null)
                {
                    var oldDirection = currDirection;
                    currDirection = mirror.Reflect(currDirection);

                    var sortingOrderOffset = oldDirection == Direction.Down || currDirection == Direction.Up ? -1 : 1;
                    AddOffset(sortingOrderOffset);

                    directionVector = currDirection.ToVector2();
                    continue;
                }
            }
            else if (hitName.StartsWith("Explosive"))
            {
                if (lastExplosiveID != hit.transform.GetInstanceID())
                {
                    lastExplosiveID = hit.transform.GetInstanceID();

                    ExplosionManager.Instance.Add(hit.collider.gameObject, hit.collider.transform.position);
                }
            }
            else if (hitName.StartsWith("Patient"))
            {
                var patient = hit.collider.GetComponent <Patient>();
                if (patient != null)
                {
                    patient.Kill(GameWorld.LevelOverReason.LaserKilledPatient);

                    AudioManager.PlaySFX("Laser Hit");
                }
            }

            var plant = hit.collider.GetComponent <Plant>();
            if (plant != null)
            {
                plant.Break();
            }

            break;
        }

        //Laser should be in front of the object when hitting from below
        if (directionVector.y > 0 && !isMirror)
        {
            AddOffset(5);
        }
        else
        {
            AddOffset(-5);
        }
        lineStrip.Draw(endpoints, offsets, endpointSize, LaserPositionOffset);

        //previousEndpoints = endpoints;
    }