Beispiel #1
0
//        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);
        }
Beispiel #2
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();
        }
Beispiel #3
0
        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);
            }
        }