private void StartWaitingForMovement() { waitingForMenuAction = false; waitingForMovement = true; unitActions.Hide(); unitActionsArea.ShowMovement(movementArea.GetPositions()); unitActionsArea.ShowAttack(movementArea.GetExtraNodes(selectedUnit.attackDistance)); }
private void StartWaitingForAttackTarget() { waitingForMenuAction = false; waitingForAttackTarget = true; unitActions.Hide(); movementArea = pathFinding.GetMovementArea(Vector2Int.RoundToInt(selectedUnit.transform.position), 0); unitActionsArea.ShowAttack(movementArea.GetExtraNodes(selectedUnit.attackDistance)); }
public void Update() { // TODO: controls state, like "if in selection mode, then allow movement" Utils.UpdateEnemiesInRange(); UpdateObstacles(); keyMapAsset.UpdateControlState(); var movement = new Vector2Int(0, 0); movement.x += keyMapAsset.leftPressed ? -1 : 0; movement.x += keyMapAsset.rightPressed ? 1 : 0; movement.y += keyMapAsset.upPressed ? 1 : 0; movement.y += keyMapAsset.downPressed ? -1 : 0; gameInfo.UpdateGameInfo(currentPlayer, currentTurn); if (showingAttackSequence) { if (keyMapAsset.button2Pressed) { attackSequence.ForceComplete(); } return; } if (showingChangeTurnSequence) { if (keyMapAsset.button2Pressed) { changeTurnSequence.ForceComplete(); } return; } // if showing a any menu and waiting for action.. var selectorOverUnit = FindObjectsOfType <Unit>() .FirstOrDefault(u => Vector2.Distance(selector.position, u.transform.position) < 0.5f); if (waitingForMenuAction) { if (keyMapAsset.button2Pressed) { buildActions.Hide(); playerActions.Hide(); unitActions.Hide(); waitingForMenuAction = false; DeselectUnit(); } return; } if (waitingForAttackTarget) { // we want to allow moving the selector while targeting a unit selector.Move(movement); AdjustCameraToSelector(); if (keyMapAsset.button1Pressed) { // if inside attack area and there is an enemy there, attack enemy var target = selectorOverUnit; var source = selectedUnit; // var activeDmg = ""; if (target != null && target.player != currentPlayer && Utils.IsInDistance(source.transform.position, target.transform.position, source.attackDistance)) { var sourceCritical = UnityEngine.Random.Range(0, 100) < source.critChance; var targetCritical = UnityEngine.Random.Range(0, 100) < target.critChance; // do damage to target // do damage back from target to unit var distance = Utils.GetDistance(source.transform.position, target.transform.position); var attackSequenceData = new AttackSequenceData() { player1UnitPrefab = source.attackSequenceUnitPrefab, player2UnitPrefab = target.attackSequenceUnitPrefab, playerAttacking = currentPlayer, counterAttack = distance <= target.attackDistance, distance = distance, player1Units = Mathf.CeilToInt(source.squadSize * source.currentHP / source.totalHP), player2Units = Mathf.CeilToInt(target.squadSize * target.currentHP / target.totalHP), p1Crit = sourceCritical, p2Crit = targetCritical, }; // var soruceDamage = source.rangedDmg; // var sourceDmg = source.rangedDmg; // // if(distance == 1) // { // sourceDmg = source.meleeDmg; // } // // var sourceDmg = (int)source.GetType().GetField(activeDmg).GetValue(source) * (source.currentHP / source.totalHP); var sourceDamage = source.rangedDmg * (source.currentHP / source.totalHP); target.currentHP -= sourceDamage + (sourceDamage * source.critMult * (sourceCritical ? 1 : 0)); Debug.Log($"{target.name} received {sourceDamage} dmg"); if (target.currentHP > 0 && attackSequenceData.counterAttack == true) { var targetDmg = target.rangedDmg * (target.currentHP / target.totalHP); source.currentHP -= targetDmg + (targetDmg * target.critMult * (targetCritical ? 1 : 0)); Debug.Log($"{source.name} received {targetDmg} dmg"); } // else // { // attackSequenceData.counterAttack = false; // } var p1CurrentUnits = Mathf.CeilToInt(source.squadSize * source.currentHP / source.totalHP); var p2CurrentUnits = Mathf.CeilToInt(target.squadSize * target.currentHP / target.totalHP); attackSequenceData.player1Killed = attackSequenceData.player1Units - p1CurrentUnits; attackSequenceData.player2Killed = attackSequenceData.player2Units - p2CurrentUnits; // show attack sequence... // TODO: show attack range + possible targets // change game state to be waiting for target selection Debug.Log("Attack!"); // consume attack source.currentActions--; // we consume movement after attack too if (source.currentMovements > 0) { source.currentMovements--; } waitingForAttackTarget = false; unitActionsArea.Hide(); DeselectUnit(); StartCoroutine(routine: StartAttackSequence(attackSequenceData, source, target)); } else if (selectorOverUnit != null && selectorOverUnit.player == selectedUnit.player) { DeselectUnit(); waitingForAttackTarget = false; SelectUnit(selectorOverUnit); } else { if (_invalidActionSfx != null) { _invalidActionSfx.Play(); } } } // is button 2 pressed, cancel if (keyMapAsset.button2Pressed) { // go back to unit actions menu // attackArea.Hide(); unitActionsArea.Hide(); DeselectUnit(); // ShowUnitActions(); waitingForAttackTarget = false; // DeselectUnit(); // waitingForAttackTarget = false; // show menu again? } return; } if (waitingForMovement) { selector.Move(movement); AdjustCameraToSelector(); if (keyMapAsset.button1Pressed) { // can't move over our structures if (selectedUnit.currentMovements > 0 && selectorOverUnit == null) { var p0 = selectedUnit.transform.position / 1; var p1 = selector.position / 1; // var obstacle = obstacles.FirstOrDefault(o => o.IsBlocked(Vector2Int.RoundToInt(selector.position))); if (movementArea.CanMove(Vector2Int.RoundToInt(p1))) { // if (Utils.IsInDistance(p0, p1, selectedUnit.movementDistance) && obstacle == null) // { selectedUnit.Move(selector.position); // selectedUnit.transform.position = selector.position; // selectedUnit.currentMovements = 0; // selectedUnit.moveDirection = p1 - p0; waitingForMovement = false; if (selectedUnit.currentActions > 0) { unitActionsArea.Hide(); StartWaitingForAttackTarget(); } else { DeselectUnit(); } } else { if (_invalidActionSfx != null) { _invalidActionSfx.Play(); } } } else if (selectorOverUnit == selectedUnit) { unitActionsArea.Hide(); waitingForMovement = false; ShowUnitActions(); } else if (selectorOverUnit != null && selectorOverUnit.player == selectedUnit.player) { DeselectUnit(); waitingForMovement = false; SelectUnit(selectorOverUnit); } else { if (_invalidActionSfx != null) { _invalidActionSfx.Play(); } } } // is button 2 pressed, cancel if (keyMapAsset.button2Pressed) { unitActionsArea.Hide(); // movementArea.Hide(); // attackArea.Hide(); DeselectUnit(); waitingForMovement = false; } return; } // if waiting for any action { selector.Move(movement); AdjustCameraToSelector(); if (keyMapAsset.button1Pressed) { // search for unit in location if (selectedUnit == null) { var unit = FindObjectsOfType <Unit>() .FirstOrDefault(u => u.player == currentPlayer && Vector2.Distance(selector.position, u.transform.position) < 0.5f); if (unit == null) { if (selectorOverUnit == null) { ShowPlayerActions(); } else { // play error selection sound } } else { SelectUnit(unit); } } } if (keyMapAsset.button2Pressed) { var playerUnits = FindObjectsOfType <Unit>().Where(u => { if (u.player != currentPlayer) { return(false); } if (u.currentMovements == 0 && u.currentActions == 0) { return(false); } // if unit and can only attack and no enemies in range.. if (u.currentMovements == 0 && u.unitType == Unit.UnitType.Unit) { return(u.enemiesInRange > 0); } // if unit is deploy, avoid it if (u.unitType == Unit.UnitType.Spawner) { return(players[u.player].resources > 0); } return(true); }).ToList(); var index = 0; var previousIndex = 0; if (selectorOverUnit != null) { index = playerUnits.IndexOf(selectorOverUnit); previousIndex = index; index++; } if (playerUnits.Count > 0) { // TODO: consider only units with possible actions, so if no targets in range // for attack, then don't consider that unit. Or maybe just consider units with movement or // spawners with action. index %= playerUnits.Count; // index = Mathf.Clamp(index, 0, playerUnits.Count - 1); var unit = playerUnits[index]; selector.position = unit.transform.position; AdjustCameraToSelector(); if (index != previousIndex) { _switchUnitSfx.Play(); } } else { ShowPlayerActions(); } } if (selectorOverUnit != null && selectedUnit == null) { unitActionsPreviewArea.Hide(); // previewArea.Hide(); unitInfo.Preview(currentPlayer, selectorOverUnit); if (selectorOverUnit.player == currentPlayer && (selectorOverUnit.currentMovements > 0 || selectorOverUnit.currentActions > 0)) { movementArea = pathFinding.GetMovementArea(Vector2Int.RoundToInt(selectorOverUnit.transform.position), selectorOverUnit.currentMovements > 0 ? selectorOverUnit.movementDistance : 0); if (selectorOverUnit.currentMovements > 0) { unitActionsPreviewArea.ShowMovement(movementArea.GetPositions()); } if (selectorOverUnit.currentActions > 0) { unitActionsPreviewArea.ShowAttack(movementArea.GetExtraNodes(selectorOverUnit.attackDistance)); } // unitActionsPreviewArea.Show(selectorOverUnit, selectorOverUnit.currentMovements > 0, // selectorOverUnit.currentActions > 0); } else if (selectorOverUnit.player != currentPlayer) { movementArea = pathFinding.GetMovementArea(Vector2Int.RoundToInt(selectorOverUnit.transform.position), selectorOverUnit.movementDistance); unitActionsPreviewArea.ShowMovement(movementArea.GetPositions()); unitActionsPreviewArea.ShowAttack(movementArea.GetExtraNodes(selectorOverUnit.attackDistance)); // unitActionsPreviewArea.Show(selectorOverUnit); } } else { unitInfo.Hide(); unitActionsPreviewArea.Hide(); // previewArea.Hide(); } if (keyMapAsset.startPressed) { gameHud.Hide(); waitingForMenuAction = true; // show options menu and wait for options generalOptionsMenu.Show(new List <Option>() { new Option { name = "Continue" }, // new Option { name = "Restart" }, new Option { name = "Main Menu" }, }, OnGeneralMenuOptionSelected, OnGeneralMenuCanceled); } }