// private GameboyButtonKeyMapAsset keyAsset; // // private void Update() // { // if (keyAsset.) // if (Input.GetKeyDown(KeyCode.T)) // { // Time.timeScale = 2; // } // // if (Input.GetKeyUp(KeyCode.T)) // { // Time.timeScale = 1; // } // } public void Show(AttackSequenceData attackData) { completed = false; player1Info.text = attackData.player1Data.name; player2Info.text = attackData.player2Data.name; this.attackData = attackData; flipTransforms.ToList().ForEach(t => t.localScale = new Vector3(attackData.playerAttacking == 0 ? 1 : -1, 1, 1)); player1Units.Clear(); player2Units.Clear(); for (var i = 0; i < player1UnitPositions.Length; i++) { for (var j = 0; j < player1UnitPositions[i].childCount; j++) { Destroy(player1UnitPositions[i].GetChild(j).gameObject); } } for (var i = 0; i < player2UnitPositions.Length; i++) { for (var j = 0; j < player2UnitPositions[i].childCount; j++) { Destroy(player2UnitPositions[i].GetChild(j).gameObject); } } for (var i = 0; i < attackData.player1Units; i++) { var unitObject = Instantiate(attackData.player1UnitPrefab, player1UnitPositions[i]); player1Units.Add(unitObject.GetComponentInChildren <UnitBig>()); } for (var i = 0; i < attackData.player2Units; i++) { var unitObject = Instantiate(attackData.player2UnitPrefab, player2UnitPositions[i]); player2Units.Add(unitObject.GetComponentInChildren <UnitBig>()); } // start animator.SetBool("Completed", false); animator.SetBool("Player1AttackReady", false); animator.SetBool("Player2AttackReady", false); animator.Play("ToPosition1", -1, 0); }
private IEnumerator StartAttackSequence(AttackSequenceData attackSequenceData, Unit source, Unit target) { // hide menues!! // dont show attack sequence if attacking a structure if (source.attackSequenceUnitPrefab != null && target.attackSequenceUnitPrefab != null && target.unitType == Unit.UnitType.Unit) { attackSequenceData.player1Data = players[0]; attackSequenceData.player2Data = players[1]; showingAttackSequence = true; var localPosition = attackSequence.transform.localPosition; attackSequence.transform.localPosition = new Vector3(0, 0, localPosition.z); attackSequence.Show(attackSequenceData); yield return(new WaitUntil(() => attackSequence.completed)); attackSequence.transform.localPosition = localPosition; showingAttackSequence = false; // TODO: center camera in unit position } if (source.currentHP <= minHealthToDestroy) { Instantiate(unitDeathPrefab, source.transform.position, Quaternion.identity); Destroy(source.gameObject); } if (target.unitType != Unit.UnitType.Unit) { Instantiate(unitDeathPrefab, target.transform.position, Quaternion.identity); // if (_unitAttackStructureSfx != null) // { // _unitAttackStructureSfx.Play(); // } } if (target.currentHP <= minHealthToDestroy) { if (target.unitType == Unit.UnitType.Unit) { Instantiate(unitDeathPrefab, target.transform.position, Quaternion.identity); Destroy(target.gameObject); } else { // can't capture if unit dies during capture (if counter attack) // or if unit cant capture or if too far away if (source == null || !source.canCapture) { target.player = -1; // leave it in 10% so you have to attack it a bit to capture it again next time target.currentHP = Mathf.CeilToInt(target.totalHP * 0.05f); Debug.Log($"{target.name} lost capture but couldn't be captured by distance or unit can't capture."); } else { target.player = source.player; var percentage = source.currentHP * 0.5f / source.totalHP; target.currentHP = Mathf.CeilToInt(target.totalHP * percentage); Debug.Log($"{target.name} captured by player {source.player} with {percentage * 100}% health"); // captured structures don't have action in this turn target.currentActions = 0; target.currentMovements = 0; } } } // Check victory condition... CheckVictoryCondition(); }
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); } }