Beispiel #1
0
    /// <summary>
    /// This function helper for create random Hexagon.
    /// </summary>
    private HexagonController CreateHexagon(Hexagon hexagon, SlotController slotController, bool isOut = false)
    {
        if (hexagon == null)
        {
            bool isBonus = Random.Range(0, 10) == 5;
            int  colorId = Random.Range(0, gameSettings.Colors.Length);

            hexagon = new Hexagon(colorId, gameSettings.Colors[colorId], isBonus);
        }

        HexagonController hexagonController = Instantiate(gameSettings.HexagonPrefab, slotController.transform, false);

        if (isOut)
        {
            hexagonController.transform.position = slotController.transform.TransformVector(new Vector3(slotController.transform.localPosition.x, InterfaceManager.Instance.GetOutScreenYAxis(CommonTypes.HEXAGON_HEIGHT), 0));
        }

        hexagonController.Initialize(hexagon, slotController);
        hexagonControllers.Add(hexagonController);

        Debug.Log($"Hexagon is Created. ColorId : {hexagonController.GetColorId()} Coordinate : {hexagonController.GetCoordinate()}");

        return(hexagonController);
    }
Beispiel #2
0
    // Tra ve ID nguoi thang
    public int isGameOver()
    {
        int  size            = GameObject.Find("Hexagon Background").GetComponent <HexagonContainerGenerator>().size;
        int  maxColumnLength = size * 2 - 1;
        bool hasAvalaibleMoveVioletPlayer = false;
        bool hasAvalaibleMoveBlackPlayer  = false;
        int  playerID = gameObject.GetComponent <Player>().playerID;

        for (int col = 1 - size; col <= size - 1; col++)
        {
            for (int row = 0; row < maxColumnLength - Mathf.Abs(col); row++)
            {
                GameObject ctn = GameObject.Find("ctn[" + col + "," + row + "]");
                if (ctn == null)
                {
                    return(0);
                }
                HexagonController controller = ctn.GetComponent <HexagonController>();
                GameObject        hexagon    = controller.getHexagon();

                if (hasAvalaibleMoveBlackPlayer && hasAvalaibleMoveVioletPlayer)
                {
                    break;
                }

                //Neu o do khong co hexagon thi bo qua
                if (hexagon == null)
                {
                    continue;
                }
                else
                {
                    if (hexagon.name.Contains("HexagonViolet"))
                    {
                        if (hasAvalaibleMoveVioletPlayer)
                        {
                            continue;
                        }
                        if (controller.getListRelativeHexagonLevel1(ctn).Count > 0)
                        {
                            hasAvalaibleMoveVioletPlayer = true;
                            continue;
                        }
                        if (controller.getListRelativeHexagonLevel2(ctn).Count > 0)
                        {
                            hasAvalaibleMoveVioletPlayer = true;
                            continue;
                        }
                    }

                    if (hexagon.name.Contains("HexagonBlack"))
                    {
                        if (hasAvalaibleMoveBlackPlayer)
                        {
                            continue;
                        }
                        if (controller.getListRelativeHexagonLevel1(ctn).Count > 0)
                        {
                            hasAvalaibleMoveBlackPlayer = true;
                            continue;
                        }
                        if (controller.getListRelativeHexagonLevel2(ctn).Count > 0)
                        {
                            hasAvalaibleMoveBlackPlayer = true;
                            continue;
                        }
                    }
                }
            }
        }


        if ((!hasAvalaibleMoveVioletPlayer && playerID == 1) || (!hasAvalaibleMoveBlackPlayer && playerID == 2))
        {
            //Tinh diem
            if (violetPointNow > blackPointNow)
            {
                return(1);
            }
            else if (violetPointNow == blackPointNow)
            {
                return(3);
            }
            else if (blackPointNow > violetPointNow)
            {
                return(2);
            }
        }

        return(0);
    }
 public HexagonInfectedState(HexagonController hex) : base(hex)
 {
     half = new Vector3(0.5f, 1f, 0.5f);
 }
Beispiel #4
0
 public HexagonStaticState(HexagonController hex) : base(hex)
 {
 }
    protected HexagonController GetHexagonFacingCenter(HexagonController origin, int hexagonsDistance = 5)
    {
        Vector3 offset;

        //Special case if origin hexagon is the center one
        if (origin.transform.position == bb.sceneCenter.transform.position)
        {
            float angle = Random.Range(0f, 365f);
            offset = Quaternion.Euler(0, angle, 0) * Vector3.forward;
            offset = offset * HexagonController.DISTANCE_BETWEEN_HEXAGONS * hexagonsDistance;
        }
        else
        {
            offset   = (bb.sceneCenter.transform.position - origin.transform.position);
            offset.y = 0;
            offset   = offset.normalized * HexagonController.DISTANCE_BETWEEN_HEXAGONS * hexagonsDistance;
        }

        Vector3 position = origin.transform.position + offset;

        position.y = 0;

        Collider[] colliders = Physics.OverlapSphere(position, HexagonController.DISTANCE_BETWEEN_HEXAGONS, HexagonController.hexagonLayer);

        if (colliders.Length == 0)
        {
            return(null);
        }

        HexagonController result         = null;
        float             targetDistance = Mathf.Pow(hexagonsDistance * HexagonController.DISTANCE_BETWEEN_HEXAGONS, 2);
        float             distanceDelta  = targetDistance;

        for (int i = 0; i < colliders.Length; ++i)
        {
            HexagonController candidate = colliders[i].GetComponent <HexagonController>();

            if (candidate.CanExitWorm())
            {
                if (result == null)
                {
                    result = candidate;
                    float distance = (colliders[i].transform.position - position).sqrMagnitude;
                    distanceDelta = Mathf.Abs(targetDistance - distance);
                }
                else
                {
                    float newDistance      = (colliders[i].transform.position - position).sqrMagnitude;
                    float newDistanceDelta = Mathf.Abs(targetDistance - newDistance);

                    if (newDistanceDelta < distanceDelta)
                    {
                        result        = candidate;
                        distanceDelta = newDistanceDelta;
                    }
                }
            }
        }

        return(result);
    }
 public HexagonMovingState(HexagonController hex) : base(hex)
 {
 }
 private void SetNeighbour(HexagonController neighbour, Neighbour position)
 {
     neighbours[(int)position] = neighbour;
 }
    void OnCollisionEnter(Collision collision)
    {
        //Stop shot
        rigidBody.velocity = Vector3.zero;
        projectileParticle.SetActive(false);

        impactParticle.GetComponent <AudioSource>().clip = wrongImpact;

        if (collision.collider.tag == "Enemy")
        {
            EnemyBaseAIBehaviour enemy = collision.collider.GetComponent <EnemyBaseAIBehaviour>();
            if (enemy == null)
            {
                enemy = collision.collider.GetComponentInParent <EnemyBaseAIBehaviour>();
            }

            if (enemy != null)
            {
                if (enemy.color == color)
                {
                    impactParticle.GetComponent <AudioSource>().clip = goodImpact;
                }

                enemy.ImpactedByShot(color, damage, transform.forward * forceMultiplier, player);
            }
        }
        else if (collision.collider.tag == "Vortex")
        {
            VortexController vortex = collision.collider.GetComponent <VortexController>();
            if (vortex != null)
            {
                vortex.ImpactedByShot(color, damage, player);
                if (vortex.Active)
                {
                    impactParticle.GetComponent <AudioSource>().clip = goodImpact;
                }
                else
                {
                    impactParticle.GetComponent <AudioSource>().clip = wrongImpact;
                }
            }
        }
        else if (collision.collider.tag == "Barrel")
        {
            CapacitorImpacted barrel = collision.collider.GetComponent <CapacitorImpacted>();
            if (barrel != null)
            {
                barrel.controller.ImpactedByShot(color, player);
            }

            impactParticle.GetComponent <AudioSource>().clip = goodImpact;
        }
        else if (collision.collider.tag == "WormBody")
        {
            WormBodySegmentController worm = collision.collider.GetComponent <WormBodySegmentController>();
            if (worm != null)
            {
                if (worm.Color == color)
                {
                    impactParticle.GetComponent <AudioSource>().clip = goodImpact;
                }

                worm.ImpactedByShot(color, damage, player);
            }
        }
        else if (collision.collider.tag == "WormHead")
        {
            WormAIBehaviour worm = collision.collider.GetComponent <WormAIBehaviour>();
            if (worm != null)
            {
                worm.ImpactedByShot(color, damage, player);
            }

            impactParticle.GetComponent <AudioSource>().clip = goodImpact;
        }
        else if (collision.collider.tag == "Hexagon")
        {
            HexagonController hexagon = collision.collider.GetComponentInParent <HexagonController>();
            if (hexagon != null)
            {
                hexagon.ImpactedByShot(player);
                if (hexagon.HasActiveTurret())
                {
                    impactParticle.GetComponent <AudioSource>().clip = goodImpact;
                }
                else
                {
                    impactParticle.GetComponent <AudioSource>().clip = wrongImpact;
                }
            }
        }

        if (collision.contacts.Length > 0)
        {
            impactParticle.transform.rotation = Quaternion.FromToRotation(Vector3.up, collision.contacts[0].normal);
        }
        impactParticle.SetActive(true);

        shotCollider.enabled = false;
        //We let the impactParticle do its job
        StartCoroutine(WaitAndReturnToPool());
    }
 public HexagonIdleState(HexagonController hex) : base(hex)
 {
     ResetCounter();
 }
    //Neighbour control
    private void CheckNeighbours()
    {
        Vector3 direction = Vector3.forward * DISTANCE_BETWEEN_HEXAGONS;

        Collider[] colliders;

        if (neighbours[(int)Neighbour.TOP] == null)
        {
            colliders = Physics.OverlapSphere(transform.position + direction, 1f, hexagonLayer);
            for (int i = 0; i < colliders.Length; ++i)
            {
                if (colliders[i].tag == "Hexagon")
                {
                    HexagonController neighbour = colliders[i].GetComponent <HexagonController>();
                    neighbours[(int)Neighbour.TOP] = neighbour;

                    neighbour.SetNeighbour(this, Neighbour.BOTTOM);

                    break;
                }
            }
        }

        direction = Quaternion.Euler(0, 60, 0) * direction;

        if (neighbours[(int)Neighbour.TOP_RIGHT] == null)
        {
            colliders = Physics.OverlapSphere(transform.position + direction, 1f, hexagonLayer);
            for (int i = 0; i < colliders.Length; ++i)
            {
                if (colliders[i].tag == "Hexagon")
                {
                    HexagonController neighbour = colliders[i].GetComponent <HexagonController>();
                    neighbours[(int)Neighbour.TOP_RIGHT] = neighbour;

                    neighbour.SetNeighbour(this, Neighbour.BOTTOM_LEFT);

                    break;
                }
            }
        }

        direction = Quaternion.Euler(0, 60, 0) * direction;

        if (neighbours[(int)Neighbour.BOTTOM_RIGHT] == null)
        {
            colliders = Physics.OverlapSphere(transform.position + direction, 1f, hexagonLayer);
            for (int i = 0; i < colliders.Length; ++i)
            {
                if (colliders[i].tag == "Hexagon")
                {
                    HexagonController neighbour = colliders[i].GetComponent <HexagonController>();
                    neighbours[(int)Neighbour.BOTTOM_RIGHT] = neighbour;

                    neighbour.SetNeighbour(this, Neighbour.TOP_LEFT);

                    break;
                }
            }
        }
    }
Beispiel #11
0
    public override WormAIBaseState Update()
    {
        switch (subState)
        {
        case SubState.WAITING:
            if (elapsedTime >= bb.BelowAttackSettingsPhase.initialWaitTime)
            {
                GameObject playerGO = rsc.enemyMng.SelectPlayerRandom();
                if (playerGO != null)
                {
                    PlayerController player = playerGO.GetComponent <PlayerController>();
                    origin = player.GetNearestHexagon();

                    if (origin != null)
                    {
                        if (!origin.isWormSelectable)
                        {
                            return(head.wanderingState);
                        }

                        head.animator.SetBool("Bite", true);

                        destiny = GetHexagonFacingCenter(origin, destinyHexagonsDistance);

                        bb.CalculateParabola(origin.transform.position, destiny.transform.position);

                        head.agent.enabled = false;

                        rotation       = 0f;
                        destinyInRange = false;
                    }
                    else
                    {
                        return(head.wanderingState);
                    }
                }
                else
                {
                    return(head.wanderingState);
                }

                origin.WormBelowAttackWarning(bb.BelowAttackSettingsPhase.adjacentDamagingCells);

                elapsedTime = 0f;
                head.attackWarningSoundFx.Play();

                subState = SubState.WARNING_PLAYER;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }

            break;

        case SubState.WARNING_PLAYER:

            if (elapsedTime >= bb.BelowAttackSettingsPhase.warningTime)
            {
                //Position head below entry point
                currentX = bb.GetJumpXGivenY(-WormBlackboard.NAVMESH_LAYER_HEIGHT, false);
                Vector3 startPosition = bb.GetJumpPositionGivenY(-WormBlackboard.NAVMESH_LAYER_HEIGHT, false);
                headTrf.position = startPosition;
                lastPosition     = startPosition;
                head.SetVisible(true);

                origin.WormBelowAttackStart();

                AttackActions();

                bb.isHeadOverground = true;
                subState            = SubState.JUMPING;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }

            break;

        case SubState.JUMPING:
            //While not again below underground navmesh layer advance
            currentX        += Time.deltaTime * bb.BelowAttackSettingsPhase.jumpSpeed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition), headTrf.up);

            float angle = bb.BelowAttackSettingsPhase.rotationSpeed * Time.deltaTime;
            headTrf.Rotate(new Vector3(0, 0, angle));
            rotation += angle;

            if (!destinyInRange)
            {
                float distanceToDestiny = (headTrf.position - destiny.transform.position).magnitude;
                if (distanceToDestiny <= destinyInRangeDistance ||
                    (headTrf.position.y < destiny.transform.position.y &&
                     currentX >= 0))    //Safety check. When jump is too fast distance can never be less than range distance
                {
                    destinyInRange = true;
                    JumpExitActions();
                    destiny.WormEnterExit();
                }
            }

            if (headTrf.position.y < -WormBlackboard.NAVMESH_LAYER_HEIGHT)
            {
                bb.isHeadOverground     = false;
                bb.tailReachedMilestone = false;
                bb.FlagCurrentWaypointAsMilestone();
                head.SetVisible(false);

                subState = SubState.EXITING;
            }
            break;

        case SubState.EXITING:
            currentX        += Time.deltaTime * bb.BelowAttackSettingsPhase.jumpSpeed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));

            if (bb.tailReachedMilestone)
            {
                //Debug.Break();
                Vector3 pos = headTrf.position;
                pos.y            = -WormBlackboard.NAVMESH_LAYER_HEIGHT;
                headTrf.position = pos;

                return(head.wanderingState);
            }
            break;

        default:
            break;
        }

        return(null);
    }
    public override WormAIBaseState Update()
    {
        switch (subState)
        {
        //Wait for head Fx and animation
        case SubState.WAITING_HEAD:
            if (elapsedTime >= bb.headDestroyedWaitTime)
            {
                if (!shouldTriggerMeteor)
                {
                    destiny = GetExitHexagon();
                    bb.CalculateParabola(headTrf.position, destiny.transform.position);
                    speed = (headTrf.position - destiny.transform.position).magnitude / bb.headDestroyedJumpDuration;

                    //Calculate start point and prior point
                    currentX = bb.GetJumpXGivenY(0, false);
                    Vector3 startPosition = bb.GetJumpPositionGivenY(0, false);
                    headTrf.position = startPosition;

                    lastPosition = bb.GetJumpPositionGivenX(currentX);

                    float   fakeNextX    = currentX + Time.deltaTime * 2;
                    Vector3 nextPosition = bb.GetJumpPositionGivenX(fakeNextX);
                    initialRotation = Quaternion.LookRotation(nextPosition - startPosition, headTrf.up);
                }

                head.animator.SetBool("Hit", false);

                bb.ConsolidateBodyParts();
                subState = SubState.WAITING_BODY;

                elapsedTime = 0f;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }
            break;

        //Wait for body parts destruction
        case SubState.WAITING_BODY:

            if (bb.wormCurrentPhase < bb.wormMaxPhases - 1 && !shouldTriggerMeteor)
            {
                headTrf.rotation = Quaternion.RotateTowards(headTrf.rotation, initialRotation, bb.headDestroyedLookRotationSpeed * Time.deltaTime);
            }

            if (elapsedTime >= bb.headDestoryedBodyWaitTime)
            {
                if (bb.wormCurrentPhase == bb.wormMaxPhases - 1)
                {
                    return(head.dyingState);
                }
                else
                {
                    head.StartNewPhase();
                    head.SetMaterial(rsc.coloredObjectsMng.GetWormHeadMaterial(bb.headCurrentChargeLevel));
                    //rsc.eventMng.TriggerEvent(EventManager.EventType.WORM_HEAD_ACTIVATED, EventInfo.emptyInfo);

                    if (shouldTriggerMeteor)
                    {
                        bb.meteorInmediate = true;
                        return(head.meteorAttackState);
                    }
                    else
                    {
                        head.animator.SetBool("MouthOpen", true);
                        subState = SubState.JUMPING;
                    }
                }
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }
            break;

        case SubState.JUMPING:
            //While not again below underground navmesh layer advance
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition), headTrf.up);

            headTrf.Rotate(new Vector3(0, 0, bb.headDestroyedRotationSpeed * Time.deltaTime));

            if (!destinyInRange)
            {
                float distanceToDestiny = (headTrf.position - destiny.transform.position).magnitude;
                if (distanceToDestiny <= destinyInRangeDistance ||
                    headTrf.position.y < destiny.transform.position.y)     //Safety check. When jump is too fast distance can never be less than range distance
                {
                    destinyInRange = true;

                    JumpExitActions();

                    destiny.WormEnterExit();
                }
            }

            if (headTrf.position.y < -WormBlackboard.NAVMESH_LAYER_HEIGHT)
            {
                SetHeadUnderground();
                head.animator.SetBool("MouthOpen", false);

                subState = SubState.EXITING;
            }
            break;

        case SubState.EXITING:
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));

            if (bb.tailReachedMilestone)
            {
                Vector3 pos = headTrf.position;
                pos.y            = -WormBlackboard.NAVMESH_LAYER_HEIGHT;
                headTrf.position = pos;

                return(head.wanderingState);
            }
            break;

        default:
            break;
        }

        return(null);
    }
    public override WormAIBaseState Update()
    {
        switch (subState)
        {
        //Underground path
        case SubState.UNDERGROUND_START:
            GameObject playerGO = rsc.enemyMng.SelectPlayerRandom();
            if (playerGO != null)
            {
                PlayerController player = playerGO.GetComponent <PlayerController>();
                origin = player.GetNearestHexagon();

                if (origin != null)
                {
                    if (!origin.isWormSelectable)
                    {
                        return(head.wanderingState);
                    }

                    destiny = GetHexagonFacingCenter(origin, 2);
                    bb.CalculateParabola(origin.transform.position, destiny.transform.position);

                    head.agent.enabled = false;
                }
                else
                {
                    return(head.wanderingState);
                }
            }
            else
            {
                return(head.wanderingState);
            }

            origin.WormEnterExit();

            elapsedTime = 0f;
            head.attackWarningSoundFx.Play();

            subState = SubState.WARNING_PLAYER;

            break;

        case SubState.WARNING_PLAYER:

            if (elapsedTime >= bb.MeteorAttackSettingsPhase.warningTime)
            {
                //Position head below entry point
                currentX = bb.GetJumpXGivenY(-WormBlackboard.NAVMESH_LAYER_HEIGHT, false);
                Vector3 startPosition = bb.GetJumpPositionGivenY(-WormBlackboard.NAVMESH_LAYER_HEIGHT, false);
                headTrf.position = startPosition;
                lastPosition     = startPosition;
                head.SetVisible(true);

                elapsedTime         = 0f;
                bb.isHeadOverground = true;
                subState            = SubState.HEAD_EXIT;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }

            break;

        case SubState.HEAD_EXIT:
            if (headTrf.position.y < 2)
            {
                currentX        += Time.deltaTime * bb.MeteorAttackSettingsPhase.enterHeadSpeed;
                lastPosition     = headTrf.position;
                headTrf.position = bb.GetJumpPositionGivenX(currentX);

                headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition), headTrf.up);

                elapsedTime += Time.deltaTime;
            }
            else
            {
                elapsedTime += bb.MeteorAttackSettingsPhase.warningTime;
                subState     = SubState.OPENING_MOUTH;
            }

            break;

        //Overground path
        case SubState.OVERGROUND_START:
            destiny = GetExitHexagon();
            bb.CalculateParabola(headTrf.position, destiny.transform.position);
            subState = SubState.OPENING_MOUTH;
            break;

        //Common path
        case SubState.OPENING_MOUTH:
            if (elapsedTime >= 1.5f)
            {
                elapsedTime = 0;
                //head.fireSpray.transform.position = head.headModel.transform.position + (Vector3.up * 0.5f);
                //head.fireSpray.transform.LookAt(head.fireSpray.transform.position + Vector3.up, head.transform.up);
                //head.fireSpray.Play();
                subState = SubState.SHOOTING;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }
            break;

        case SubState.SHOOTING:
            if (totalShots < bb.MeteorAttackSettingsPhase.numberOfThrownMeteors)
            {
                if (elapsedTime <= 0)
                {
                    MeteorController meteor = rsc.poolMng.meteorPool.GetObject();
                    meteor.transform.position = head.meteorSpawnPoint.position;
                    meteor.GoUp(bb.MeteorAttackSettingsPhase.speedOfThrownMeteors);

                    rsc.rumbleMng.Rumble(0, 0.15f, 0, 0.6f);
                    rsc.camerasMng.PlayEffect(0, 0.1f, 0.3f);

                    ++totalShots;
                    elapsedTime = timeBetweenShots;
                }
                else
                {
                    elapsedTime -= Time.deltaTime;
                }
            }
            else
            {
                speed = (headTrf.position - destiny.transform.position).magnitude / bb.MeteorAttackSettingsPhase.jumpDuration;

                //Calculate start point and prior point
                currentX = bb.GetJumpXGivenY(headTrf.position.y, false);
                Vector3 startPosition = bb.GetJumpPositionGivenY(headTrf.position.y, false);
                headTrf.position = startPosition;

                lastPosition = bb.GetJumpPositionGivenX(currentX);

                float   fakeNextX    = currentX + Time.deltaTime * 2;
                Vector3 nextPosition = bb.GetJumpPositionGivenX(fakeNextX);
                initialRotation = Quaternion.LookRotation(nextPosition - startPosition, headTrf.up);

                head.fireSpray.Stop();

                elapsedTime = 0;
                if (underground)
                {
                    head.animator.SetBool("MouthOpen", false);
                }
                else
                {
                    head.animator.SetBool("MouthOpenTrans", false);
                    head.animator.SetBool("Jump", true);
                }
                subState = SubState.CLOSING_MOUTH;
            }
            break;

        case SubState.CLOSING_MOUTH:
            headTrf.rotation = Quaternion.RotateTowards(headTrf.rotation, initialRotation, bb.headDestroyedLookRotationSpeed * Time.deltaTime);
            if (elapsedTime >= 1)
            {
                elapsedTime = 0;
                subState    = SubState.JUMPING;
                head.animator.SetBool("Jump", false);
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }
            break;

        case SubState.JUMPING:
            //While not again below underground navmesh layer advance
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition), headTrf.up);

            headTrf.Rotate(new Vector3(0, 0, bb.MeteorAttackSettingsPhase.rotationSpeed * Time.deltaTime));

            if (!destinyInRange)
            {
                float distanceToDestiny = (headTrf.position - destiny.transform.position).magnitude;
                if (distanceToDestiny <= destinyInRangeDistance ||
                    headTrf.position.y < destiny.transform.position.y)     //Safety check. When jump is too fast distance can never be less than range distance
                {
                    destinyInRange = true;

                    JumpExitActions();

                    destiny.WormEnterExit();
                }
            }

            if (headTrf.position.y < -WormBlackboard.NAVMESH_LAYER_HEIGHT)
            {
                SetHeadUnderground();

                subState = SubState.EXITING;
            }
            break;

        case SubState.EXITING:
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));

            if (bb.tailReachedMilestone)
            {
                Vector3 pos = headTrf.position;
                pos.y            = -WormBlackboard.NAVMESH_LAYER_HEIGHT;
                headTrf.position = pos;

                //Trigger meteor rain
                MeteorAttackEventInfo info = MeteorAttackEventInfo.eventInfo;
                WormBlackboard.MeteorAttackSettings settings = bb.MeteorAttackSettingsPhase;

                info.meteorInitialBurst = settings.meteorInitialBurst;
                info.meteorRainDuration = settings.meteorRainDuration;
                info.meteorInterval     = settings.meteorInterval;
                info.meteorsPerInterval = settings.meteorsPerInterval;
                info.meteorWaitTime     = settings.meteorWaitTime;
                info.meteorWarningTime  = settings.meteorWarningTime;

                rsc.eventMng.TriggerEvent(EventManager.EventType.METEOR_RAIN_START, info);
                subState = SubState.WAITING_METEOR_RAIN;
            }
            break;

        case SubState.WAITING_METEOR_RAIN:
            //Wait
            break;

        case SubState.METEOR_RAIN_ENDED:
            return(head.wanderingState);

        default:
            break;
        }

        return(null);
    }
Beispiel #14
0
    /// <summary>
    /// This function returns true if there are any moves left.
    /// </summary>
    /// <returns></returns>
    public async UniTask CheckGameOver()
    {
        await UniTask.Yield();

        foreach (HexagonController hexagonController in hexagonControllers)
        {
            bool isAnyColorMatch = false;
            HexagonController otherHexagonController = null;

            foreach (Direction direction in (Direction[])Enum.GetValues(typeof(Direction)))
            {
                List <HexagonController> neighboursHexagonControllers = hexagonController.GetNeighboursHexagonControllers(direction);

                foreach (HexagonController neighboursHexagonController in neighboursHexagonControllers)
                {
                    if (hexagonController.GetColorId() == neighboursHexagonController.GetColorId())
                    {
                        otherHexagonController = neighboursHexagonController;
                        isAnyColorMatch        = true;
                        break;
                    }
                }

                if (isAnyColorMatch)
                {
                    break;
                }
            }

            if (!isAnyColorMatch)
            {
                continue;
            }

            if (otherHexagonController == null)
            {
                continue;
            }

            Coordinate[] extractHexagonCoordinates =
            {
                hexagonController.GetCoordinate(),
                otherHexagonController.GetCoordinate()
            };

            List <HexagonController> possibleHexagonControllers = new List <HexagonController>();

            Coordinate currentHexagonCoordinate = hexagonController.GetCoordinate();
            Coordinate otherHexagonCoordinate   = otherHexagonController.GetCoordinate();

            if (currentHexagonCoordinate.x == otherHexagonCoordinate.x)
            {
                if (currentHexagonCoordinate.x % 2 == 0)
                {
                    HexagonController targetHexagonController = currentHexagonCoordinate.y < otherHexagonCoordinate.y ? hexagonController : otherHexagonController;

                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(targetHexagonController.GetCoordinate() + new Coordinate(1, 0), true));
                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(targetHexagonController.GetCoordinate() + new Coordinate(-1, 0), true));
                }
                else
                {
                    HexagonController targetHexagonController = currentHexagonCoordinate.y > otherHexagonCoordinate.y ? hexagonController : otherHexagonController;

                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(targetHexagonController.GetCoordinate() + new Coordinate(1, 0), true));
                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(targetHexagonController.GetCoordinate() + new Coordinate(-1, 0), true));
                }
            }
            else
            {
                if (currentHexagonCoordinate.y == otherHexagonCoordinate.y)
                {
                    HexagonController evenHexagonController = currentHexagonCoordinate.x % 2 == 0 ? hexagonController : otherHexagonController;
                    HexagonController oddHexagonController  = currentHexagonCoordinate.x % 2 != 0 ? hexagonController : otherHexagonController;

                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(oddHexagonController.GetCoordinate() + new Coordinate(0, -1), true));
                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(evenHexagonController.GetCoordinate() + new Coordinate(0, 1), true));
                }
                else
                {
                    HexagonController smallerYAxisHexagonController = currentHexagonCoordinate.y < otherHexagonCoordinate.y ? hexagonController : otherHexagonController;
                    HexagonController greaterYAxisHexagonController = currentHexagonCoordinate.y > otherHexagonCoordinate.y ? hexagonController : otherHexagonController;

                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(greaterYAxisHexagonController.GetCoordinate() + new Coordinate(0, -1), true));
                    possibleHexagonControllers.Add(GetHexagonControllerByCoordinate(smallerYAxisHexagonController.GetCoordinate() + new Coordinate(0, 1), true));
                }
            }

            possibleHexagonControllers.RemoveAll(x => x == null);

            foreach (HexagonController possibleHexagonController in possibleHexagonControllers)
            {
                if (possibleHexagonController.CanBeColor(hexagonController.GetColorId(), extractHexagonCoordinates))
                {
                    Debug.Log($"Move Caught. Coordinate : {possibleHexagonController.GetCoordinate()}");

                    return;
                }
            }
        }

        Debug.Log("Player Has No More Moves to Play!");
        GameManager.Instance.GameOver(1);
    }
 public HexagonAboveAttackAdjacentState(HexagonController hex) : base(hex)
 {
 }
 public HexagonBaseState(HexagonController hex)
 {
     this.hex = hex;
 }
 public HexagonEnterExitState(HexagonController hex) : base(hex)
 {
 }
 public HexagonBelowAttackWallState(HexagonController hex) : base(hex)
 {
 }
    public override WormAIBaseState Update()
    {
        switch (subState)
        {
        case SubState.KNOCKED_OUT:
            if (elapsedTime >= bb.HealthSettingsPhase.knockOutTime)
            {
                //Restore
                head.recoverSoundFx.Play();
                head.ResetPhase();

                destiny = GetExitHexagon();
                bb.CalculateParabola(headTrf.position, destiny.transform.position);
                speed = (headTrf.position - destiny.transform.position).magnitude / bb.headDestroyedJumpDuration;

                //Calculate start point and prior point
                currentX = bb.GetJumpXGivenY(0, false);
                Vector3 startPosition = bb.GetJumpPositionGivenY(0, false);
                headTrf.position = startPosition;

                lastPosition = bb.GetJumpPositionGivenX(currentX);

                float   fakeNextX    = currentX + Time.deltaTime * 2;
                Vector3 nextPosition = bb.GetJumpPositionGivenX(fakeNextX);
                initialRotation = Quaternion.LookRotation(nextPosition - startPosition, headTrf.up);

                head.animator.SetBool("Stunned", false);
                head.animator.SetBool("MouthOpen", true);
                elapsedTime = 0f;

                head.SetInvulnerable();

                subState = SubState.MOVING_HEAD;
            }
            else
            {
                if (elapsedTime >= 3f && !knockOutTutorialTriggered)
                {
                    knockOutTutorialTriggered        = true;
                    TutorialEventInfo.eventInfo.type = TutorialManager.Type.HIT_BOSS_HEAD;
                    rsc.eventMng.TriggerEvent(EventManager.EventType.SHOW_TUTORIAL, TutorialEventInfo.eventInfo);
                }

                elapsedTime += Time.deltaTime;
            }
            break;

        case SubState.MOVING_HEAD:
            headTrf.rotation = Quaternion.RotateTowards(headTrf.rotation, initialRotation, bb.headDestroyedLookRotationSpeed * Time.deltaTime);

            if (elapsedTime >= bb.headDestoryedBodyWaitTime)
            {
                subState = SubState.JUMPING;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }
            break;

        case SubState.JUMPING:
            //While not again below underground navmesh layer advance
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition), headTrf.up);

            headTrf.Rotate(new Vector3(0, 0, bb.headDestroyedRotationSpeed * Time.deltaTime));

            if (!destinyInRange)
            {
                float distanceToDestiny = (headTrf.position - destiny.transform.position).magnitude;
                if (distanceToDestiny <= destinyInRangeDistance ||
                    headTrf.position.y < destiny.transform.position.y)     //Safety check. When jump is too fast distance can never be less than range distance
                {
                    destinyInRange = true;

                    JumpExitActions();

                    destiny.WormEnterExit();
                }
            }

            if (headTrf.position.y < -WormBlackboard.NAVMESH_LAYER_HEIGHT)
            {
                SetHeadUnderground();
                head.animator.SetBool("MouthOpen", false);

                subState = SubState.EXITING;
            }
            break;

        case SubState.EXITING:
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));

            if (bb.tailReachedMilestone)
            {
                Vector3 pos = headTrf.position;
                pos.y            = -WormBlackboard.NAVMESH_LAYER_HEIGHT;
                headTrf.position = pos;

                return(head.wanderingState);
            }
            break;

        default:
            break;
        }

        return(null);
    }
 public HexagonBorderWallState(HexagonController hex) : base(hex)
 {
 }
Beispiel #21
0
    public override WormAIBaseState Update()
    {
        switch (subState)
        {
        case SubState.WAITING:
            if (elapsedTime >= bb.WanderingSettingsPhase.initialWaitTime)
            {
                head.agent.enabled = false;

                currentWP = route.wayPoints[WPIndex].transform.position;
                nextWP    = route.wayPoints[WPIndex + 1].transform.position;

                currentWPUG = currentWP - bb.navMeshLayersDistance;
                nextWPUG    = nextWP - bb.navMeshLayersDistance;

                headTrf.position = currentWPUG;
                headTrf.LookAt(nextWPUG, Vector3.up);
                bb.CalculateWorldEnterBezierPoints(headTrf);
                head.SetVisible(true);

                //Rotate head
                Vector3 headUp = currentWPUG - nextWPUG;
                headTrf.LookAt(currentWP, headUp);

                t = 0;

                HexagonController hexagon = route.wayPoints[WPIndex].GetComponent <HexagonController>();
                hexagon.WormEnterExit();

                EnterExitActions();
                head.animator.SetBool("MouthOpen", true);

                bb.isHeadOverground = true;
                bb.applySinMovement = true;

                subState = SubState.ENTERING;
            }
            else
            {
                elapsedTime += Time.deltaTime;
            }

            break;

        case SubState.ENTERING:
            if (t <= 2)
            {
                shouldMove    = Time.deltaTime * bb.WanderingSettingsPhase.wanderingSpeed;
                actuallyMoved = 0;
                lastPosition  = headTrf.position;
                Vector3 newPos = Vector3.zero;

                while (actuallyMoved < shouldMove && t <= 2)
                {
                    newPos = bb.GetEnterCurvePosition(currentWPUG, nextWP, t);

                    actuallyMoved = (newPos - lastPosition).magnitude;

                    t += Time.deltaTime / duration;
                }
                headTrf.position = newPos;
                headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));
            }
            else
            {
                ++WPIndex;
                currentWP = route.wayPoints[WPIndex].transform.position;

                head.agent.areaMask = WormBlackboard.NAVMESH_FLOOR_LAYER;
                head.agent.enabled  = true;
                head.agent.speed    = bb.WanderingSettingsPhase.wanderingSpeed;
                head.agent.SetDestination(currentWP);

                head.animator.SetBool("MouthOpen", false);

                bb.meteorInmediate = true;
                elapsedTime        = 0;

                subState = SubState.FOLLOWING_PATH;
            }

            break;

        case SubState.FOLLOWING_PATH:

            if (bb.AboveAttackSettingsPhase.active && head.CheckPlayerInSight(bb.AboveAttackSettingsPhase.exposureMinHexagons, bb.AboveAttackSettingsPhase.exposureMaxHexagons, false))
            {
                bb.aboveAttackCurrentExposureTime += Time.deltaTime;

                if (!angryEyes)
                {
                    angryEyes = true;
                    head.WatchingPlayer();
                }
            }
            else
            {
                if (angryEyes)
                {
                    angryEyes = false;
                    head.NotWatchingPlayer();
                }
            }

            if (bb.attacksEnabled && bb.AboveAttackSettingsPhase.active && bb.aboveAttackCurrentExposureTime >= bb.AboveAttackSettingsPhase.exposureTimeNeeded &&
                bb.aboveAttackCurrentCooldownTime >= bb.AboveAttackSettingsPhase.cooldownTime &&
                head.CheckPlayerInSight(bb.AboveAttackSettingsPhase.attackMinHexagons, bb.AboveAttackSettingsPhase.attackMaxHexagons, true))
            {
                if (bb.playerInSight != null)
                {
                    HexagonController destiny = bb.playerInSight.GetNearestHexagon();

                    if (destiny != null && destiny.isWormSelectable)
                    {
                        if (angryEyes)
                        {
                            angryEyes = false;
                            head.NotWatchingPlayer();
                        }
                        return(head.aboveAttackState);
                    }
                }
            }

            //Not reached next waypoint
            if (elapsedTime >= 6f)
            {
                head.agent.enabled = false;

                destiny = GetExitHexagon();
                bb.CalculateParabola(headTrf.position, destiny.transform.position);
                speed = (headTrf.position - destiny.transform.position).magnitude / bb.headDestroyedJumpDuration;

                //Calculate start point and prior point
                currentX = bb.GetJumpXGivenY(0, false);
                Vector3 startPosition = bb.GetJumpPositionGivenY(0, false);
                headTrf.position = startPosition;

                lastPosition = bb.GetJumpPositionGivenX(currentX);

                float   fakeNextX    = currentX + Time.deltaTime * 2;
                Vector3 nextPosition = bb.GetJumpPositionGivenX(fakeNextX);
                headTrf.rotation = Quaternion.LookRotation(nextPosition - startPosition, headTrf.up);

                subState = SubState.JUMPING;
            }
            else
            {
                elapsedTime += Time.deltaTime;

                if (!head.agent.hasPath || (head.agent.hasPath && head.agent.remainingDistance <= 0.25))
                {
                    if (WPIndex == route.wayPoints.Length - 2)
                    {
                        head.agent.enabled = false;

                        currentWP = route.wayPoints[WPIndex].transform.position;
                        nextWP    = route.wayPoints[WPIndex + 1].transform.position;

                        currentWPUG = currentWP - bb.navMeshLayersDistance;
                        nextWPUG    = nextWP - bb.navMeshLayersDistance;

                        headTrf.LookAt(nextWP, Vector3.up);

                        bb.CalculateWorldExitBezierPoints(headTrf);

                        t = 0;

                        HexagonController hexagon = route.wayPoints[WPIndex + 1].GetComponent <HexagonController>();
                        hexagon.WormEnterExit();

                        if (angryEyes)
                        {
                            angryEyes = false;
                            head.NotWatchingPlayer();
                        }

                        head.animator.SetBool("MouthOpen", true);
                        bb.meteorInmediate = false;

                        subState = SubState.EXITING;
                    }
                    else
                    {
                        elapsedTime = 0;
                        ++WPIndex;
                        currentWP = route.wayPoints[WPIndex].transform.position;
                        head.agent.SetDestination(currentWP);
                    }
                }
            }

            break;

        case SubState.EXITING:
            if (t <= 2)
            {
                shouldMove    = Time.deltaTime * bb.WanderingSettingsPhase.wanderingSpeed;
                actuallyMoved = 0;
                lastPosition  = headTrf.position;
                Vector3 newPos = Vector3.zero;

                if (t >= 1.6f && !exitRumble)
                {
                    exitRumble = true;
                    EnterExitActions();
                }

                while (actuallyMoved < shouldMove && t <= 2)
                {
                    newPos        = bb.GetExitCurvePosition(currentWP, nextWPUG, t);
                    actuallyMoved = (newPos - lastPosition).magnitude;

                    t += Time.deltaTime / duration;
                }
                headTrf.position = newPos;
                headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));
            }
            else
            {
                SetUndergroundDirection();
                SetHeadUnderground();
                head.animator.SetBool("MouthOpen", false);

                subState = SubState.WAITING_FOR_TAIL;
            }

            break;

        case SubState.WAITING_FOR_TAIL:

            //move head until tail is undeground
            if (!bb.tailReachedMilestone)
            {
                MoveUndergroundDirection();
            }
            else
            {
                bb.applySinMovement = false;

                if (bb.shouldMeteorBeTriggedAfterWandering)
                {
                    return(head.meteorAttackState);
                }
                //If some random condition attack, else new wandering state
                else if (bb.attacksEnabled && bb.BelowAttackSettingsPhase.active &&
                         Random.Range(0f, 1f) <= bb.BelowAttackSettingsPhase.chancesOfBelowAttackAfterWandering / 100)
                {
                    return(head.belowAttackState);
                }
                else
                {
                    SetInitialState();
                }
            }

            break;


        //Failsafe exit
        case SubState.JUMPING:
            //While not again below underground navmesh layer advance
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition), headTrf.up);

            if (!destinyInRange)
            {
                float distanceToDestiny = (headTrf.position - destiny.transform.position).magnitude;
                if (distanceToDestiny <= destinyInRangeDistance ||
                    headTrf.position.y < destiny.transform.position.y)     //Safety check. When jump is too fast distance can never be less than range distance
                {
                    destinyInRange = true;

                    JumpExitActions();

                    destiny.WormEnterExit();
                }
            }

            if (headTrf.position.y < -WormBlackboard.NAVMESH_LAYER_HEIGHT)
            {
                SetHeadUnderground();
                head.animator.SetBool("MouthOpen", false);

                subState = SubState.JUMP_EXITING;
            }
            break;

        case SubState.JUMP_EXITING:
            currentX        += Time.deltaTime * speed;
            lastPosition     = headTrf.position;
            headTrf.position = bb.GetJumpPositionGivenX(currentX);

            headTrf.LookAt(headTrf.position + (headTrf.position - lastPosition));

            if (bb.tailReachedMilestone)
            {
                Vector3 pos = headTrf.position;
                pos.y            = -WormBlackboard.NAVMESH_LAYER_HEIGHT;
                headTrf.position = pos;

                return(head.wanderingState);
            }
            break;

        default:
            break;
        }

        return(null);
    }
 private void Awake()
 {
     SetLevel();
     instance = this;
 }
 /// <summary>
 /// This function helper for set Hexagon controller.
 /// </summary>
 public void SetHexagonController(HexagonController hexagonController)
 {
     this.hexagonController = hexagonController;
 }
 public HexagonBelowAttackAdjacentState(HexagonController hex) : base(hex)
 {
 }
Beispiel #25
0
 public HexagonMeteorAttackState(HexagonController hex) : base(hex)
 {
 }