/// <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); }
// 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); }
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; } } } }
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); }
/// <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) { }
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) { }
public HexagonMeteorAttackState(HexagonController hex) : base(hex) { }