Ejemplo n.º 1
0
        //向目标地点使用技能
        public void UseSkill(List <BattleAction> actions, GridUnit target, BattleSkillAnalysis skillAnalysis)
        {
            if (target == null || skillAnalysis == null)
            {
                UtilityHelper.LogError("Use skill error, none target or skill");
                return;
            }

            List <BattleHeroSkillResult> skillResults = new List <BattleHeroSkillResult>();

            for (int i = 0; i < skillAnalysis.suitableUnits.Count; ++i)
            {
                //范围内的都受到伤害
                if (target.Distance(skillAnalysis.suitableUnits[i].mapGrid) <= skillAnalysis.battleSkill.rangeRadius)
                {
                    skillResults.Add(BattleCalculator.Instance.CalcSingle(this, skillAnalysis.suitableUnits[i], skillAnalysis.battleSkill));
                }
            }

            //产生使用技能的动作
            if (actions != null)
            {
                BattleHeroSkillAction action = new BattleHeroSkillAction(this, skillAnalysis.battleSkill.skillID);
                action.skillResult = skillResults.ToArray();
                actions.Add(action);
            }

            //产生伤害
            for (int i = 0; i < skillResults.Count; ++i)
            {
                skillResults[i].battleUnit.AcceptSkillResult(skillResults[i].syncAttribute, actions);
            }
        }
Ejemplo n.º 2
0
        //点击了地块、战斗单位 -- 在当前是选择移动目标的情况下
        private void OnBattleUnitAndGridTouched_StateMove(GridUnit gridTouched, BattleUnit battleUnitTouched)
        {
            //点中了战斗单位
            if (battleUnitTouched != null)
            {
                //显示战斗单位的详情
                UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
            }
            //点中了地图
            else
            {
                //障碍物不能作为移动目标(暂时)
                if (gridTouched.GridType == GridType.Obstacle)
                {
                    UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                }
                else
                {
                    //点击是否超出了范围
                    GridUnit fromGrid = manualOperatingBattleUnitRenderer.battleUnit.mapGrid;
                    if (fromGrid.Distance(gridTouched) > manualOperatingBattleUnitRenderer.battleUnit.battleUnitAttribute.mobility)
                    {
                        UtilityHelper.Log("超出了移动半径!");
                        UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                    }
                    else
                    {
                        //判断移动是否可以到达
                        bool result = MapNavigator.Instance.Navigate(
                            fieldRenderer.battleField.battleMap,
                            fromGrid,
                            gridTouched,
                            UtilityObjs.gridUnits,
                            null,
                            manualOperatingBattleUnitRenderer.battleUnit.battleUnitAttribute.mobility
                            );

                        //判断是否可以到达(导航成功且可以可以到达)
                        if (result && UtilityObjs.gridUnits[UtilityObjs.gridUnits.Count - 1].Equals(gridTouched))
                        {
                            //可以到达
                            ManualMoveTo(gridTouched, UtilityObjs.gridUnits.ToArray());
                            UtilityObjs.gridUnits.Clear();
                        }
                        else
                        {
                            //不可以到达
                            UtilityHelper.Log("点击位置不可到达!");
                            UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                        }
                    }
                }
            }
        }
Ejemplo n.º 3
0
        //自动选择目标
        private void AutoSelectTarget(BattleUnitAction battleUnitAction)
        {
            int stopDistance = SkillStopDistance;
            //从仇恨列表中确定目标
            BattleUnit hatredUnit = null;

            //按照仇恨列表获取目标
            for (int i = 0; i < hatredRecorder.HatredCount; ++i)
            {
                hatredUnit = hatredRecorder.GetHatredByIdx(i, i == 0);
                if (!hatredUnit.CanAction)
                {
                    //已经排序过了,找到不能行动的单位,就表示没有单位可以行动了
                    hatredUnit = null;
                    break;
                }

                //判断这个单位是否可以到达
                bool catched = false;
                //如果这个单位就在身边
                if (mapGrid.Distance(hatredUnit.mapGrid) <= stopDistance)
                {
                    toTargetPath.Clear();
                    catched = true;
                }
                else
                {
                    catched = MapNavigator.Instance.Navigate(
                        battleField.battleMap,
                        mapGrid,
                        hatredUnit.mapGrid,
                        toTargetPath,
                        null,
                        battleUnitAttribute.mobility,
                        stopDistance
                        );
                }

                //寻路不可达
                if (!catched)
                {
                    hatredUnit = null;
                    continue;
                }
                //找到了
                else
                {
                    break;
                }
            }

            //没有目标
            if (hatredUnit == null)
            {
                targetBattleUnit = null;
                return;
            }

            //判断是否切换目标
            if (battleUnitAction != null && !hatredUnit.Equals(targetBattleUnit))
            {
                battleUnitAction.changeTargetAction = BattleUnitChangeTargetAction.Get();
                battleUnitAction.changeTargetAction.lastTargetUnit = targetBattleUnit;
                battleUnitAction.changeTargetAction.newTargetUnit  = hatredUnit;
                targetBattleUnit = hatredUnit;
            }
        }
Ejemplo n.º 4
0
        //搜索目标
        private TargetSearchResult SearchTarget(List <BattleAction> actions)
        {
            //按照距离排序敌人
            UtilityObjs.battleUnits.Clear();
            //只考虑可以行动的
            for (int i = 0; i < enemyTeam.battleUnits.Count; ++i)
            {
                if (enemyTeam.battleUnits[i].CanAction)
                {
                    UtilityObjs.battleUnits.Add(enemyTeam.battleUnits[i]);
                }
            }

            //天下无敌了,还有谁??
            if (UtilityObjs.battleUnits.Count == 0)
            {
                return(TargetSearchResult.Inexistence);
            }

            //结果类型
            TargetSearchResult searchResult = TargetSearchResult.InRange;

            //按照距离排序
            UtilityObjs.battleUnits.Sort(delegate(BattleUnit b1, BattleUnit b2)
            {
                return(mapGrid.Distance(b1.mapGrid) - mapGrid.Distance(b2.mapGrid));
            });

            //暂时不添加复杂的逻辑,只选择直线距离最近的
            BattleUnit newTarget     = null;
            GridUnit   newTargetGrid = null;

            for (int i = 0; i < UtilityObjs.battleUnits.Count; ++i)
            {
                //如果当前目标就在范围内
                if (mapGrid.Distance(UtilityObjs.battleUnits[i].mapGrid) <= 1)
                {
                    //设置目标,但是不需要移动
                    newTarget = UtilityObjs.battleUnits[i];
                    toTargetPath.Clear();
                    targetGrid   = null;
                    searchResult = TargetSearchResult.InRange;
                    break;
                }

                //目标不在周围需要移动
                newTargetGrid = battleField.battleMap.GetEmptyGrid(mapGrid, UtilityObjs.battleUnits[i].mapGrid, toTargetPath, mobility);
                if (newTargetGrid == null)
                {
                    //UtilityHelper.LogWarning(battleUnitID + "找不到空格子了,看看下一个吧");
                    continue;
                }
                else
                {
                    newTarget    = UtilityObjs.battleUnits[i];
                    searchResult = TargetSearchResult.NeedMove;
                    break;
                }
            }

            if (newTarget == null)
            {
                UtilityHelper.LogWarning("确实找不到了");
                targetBattleUnit = null;
                targetGrid       = null;
                toTargetPath.Clear();
                if (actions != null)
                {
                    //创建一个warning
                    BattleHeroWarningAction action = new BattleHeroWarningAction(this, "No target:" + battleUnitID);
                    actions.Add(action);
                }
                return(TargetSearchResult.Inexistence);
            }

            //目标不一致,切换目标
            if (targetBattleUnit != newTarget)
            {
                //切换目标
                BattleHeroChangeTargetAction action = new BattleHeroChangeTargetAction(this);
                action.lastTargetUnit = targetBattleUnit;
                action.newTargetUnit  = newTarget;

                //设置当前目标以及格子
                targetBattleUnit = newTarget;
                actions.Add(action);
            }

            //移动的格子重新设置
            targetGrid = newTargetGrid;

            return(searchResult);
        }
Ejemplo n.º 5
0
        private void OnBattleUnitAndGridTouched(GridUnit gridTouched, BattleUnit battleUnitTouched)
        {
            //没有激活操作状态
            if (manualOperationState == ManualOperationState.None)
            {
                //点中了战斗单位
                if (battleUnitTouched != null)
                {
                    //点中了等待手动操作的战斗单位
                    if (battleUnitTouched.battleUnitRenderer.Equals(manualBattleUnitRenderer))
                    {
                        ShowManualActionList();
                    }
                    else
                    {
                        UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                    }
                }
                //点中了地图
                else
                {
                    UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                }
            }
            //选择移动状态
            else if (manualOperationState == ManualOperationState.Move)
            {
                //点中了战斗单位
                if (battleUnitTouched != null)
                {
                    //点中了等待手动操作的战斗单位
                    if (battleUnitTouched.battleUnitRenderer.Equals(manualBattleUnitRenderer))
                    {
                        //取消操作
                        manualOperationState = ManualOperationState.None;
                        SetRangeHighlightActive(false, 0, 0, 0);
                    }
                    else
                    {
                        UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                    }
                }
                //点中了地图
                else
                {
                    if (gridTouched.GridType == GridType.Obstacle)
                    {
                        UIViewManager.Instance.ShowView(UIViewName.BattleFieldUnitInfo, gridTouched, battleUnitTouched);
                    }
                    else
                    {
                        //点击是否超出了范围
                        GridUnit fromGrid = manualBattleUnitRenderer.battleUnit.mapGrid;
                        if (fromGrid.Distance(gridTouched) > manualBattleUnitRenderer.battleUnit.mobility)
                        {
                            Debug.Log("超出了移动半径!");
                        }
                        else
                        {
                            bool result = MapNavigator.Instance.Navigate(
                                battleField.battleMap,
                                fromGrid,
                                gridTouched,
                                UtilityObjs.gridUnits,
                                null,
                                manualBattleUnitRenderer.battleUnit.mobility
                                );

                            //判断是否可以到达(导航成功且可以可以到达)
                            if (result && UtilityObjs.gridUnits[UtilityObjs.gridUnits.Count - 1].Equals(gridTouched))
                            {
                                //可以到达
                                ManualMoveTo(gridTouched, UtilityObjs.gridUnits.ToArray());
                                UtilityObjs.gridUnits.Clear();
                            }
                            else
                            {
                                //不可以到达
                                Debug.Log("点击位置不可到达!");
                            }
                        }
                    }
                }
            }
            //选择攻击目标状态
            else if (manualOperationState == ManualOperationState.Skill)
            {
                //点中了战斗单位
                if (battleUnitTouched != null)
                {
                    //点中了等待手动操作的战斗单位
                    if (battleUnitTouched.battleUnitRenderer.Equals(manualBattleUnitRenderer))
                    {
                        //取消操作
                        manualOperationState = ManualOperationState.None;
                        SetRangeHighlightActive(false, 0, 0, 0);
                    }
                    else
                    {
                        //判断是否可以被攻击
                        if (manualBattleUnitRenderer.battleUnit.battleTeam.Equals(battleUnitTouched.battleTeam))
                        {
                            //同一个队伍的
                            Debug.Log("攻击状态点中了同一个队伍的战斗单位:" + battleUnitTouched.ToString());
                        }
                        else if (battleUnitTouched.mapGrid.Distance(manualBattleUnitRenderer.battleUnit.mapGrid) > 1)
                        {
                            Debug.Log("不在攻击范围:" + battleUnitTouched.ToString());
                        }
                        else
                        {
                            ManualSkill(battleUnitTouched);
                        }
                    }
                }
                //点中了地图
                else
                {
                    Debug.Log("攻击状态点中了地图单位:" + gridTouched.ToString());
                }
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 导航至某个位置
        /// </summary>
        /// <returns>The navigate.</returns>
        /// <param name="battleMap">地图</param>
        /// <param name="from">起始格子</param>
        /// <param name="to">目标格子</param>
        /// <param name="path">保存导航路径</param>
        /// <param name="searched">搜索过的路径</param>
        /// <param name="mobility">步数限制(移动区域半径)</param>
        /// <param name="stopDistance">距离目标的停止距离</param>
        /// <param name="containsTargetGrid">路径是否包含目标</param>
        public bool Navigate(
            BattleMap battleMap,
            GridUnit from,
            GridUnit to,
            List <GridUnit> path,
            List <GridUnit> searched = null,
            int mobility             = -1,
            int stopDistance         = 0)
        {
            //没有设置地图
            if (battleMap == null)
            {
                return(false);
            }

            if (path != null)
            {
                path.Clear();
            }

            if (searched != null)
            {
                searched.Clear();
            }

            //这种情况基本上也就不用寻路了吧...
            if (to.runtimePasses == 0 &&
                stopDistance <= 1 &&
                from.Distance(to) > 1)
            {
                return(false);
            }

            //本来就在停止距离内
            if (from.Distance(to) <= stopDistance)
            {
                return(true);
            }

            int tryTimes = battleMap.GridCount;

            List <NavigationData> opening = new List <NavigationData>();

            opening.Add(GetEmptyNavigationData(from, null, 0, from.Distance(to)));

            int  retry   = 0;
            bool catched = false;

            //当前探索方向
            int curDir = 0;
            //上次探索方向
            int lastDir = 0;
            //每次检测方向的次数
            int checkTimes = 0;

            //判断是否需要遍历open列表
            NavigationData gift = null;

            //距离最近的格子(接下来要移动的)
            NavigationData next_0 = null;
            //距离次近的格子
            NavigationData next_1 = null;

            int minStep = EGameConstL.Infinity;

            while (retry <= tryTimes && !catched)
            {
                ++retry;
                //从open中查找最近的节点
                if (gift != null)
                {
                    next_0 = gift;
                    gift   = null;
                }
                else if (next_1 != null)
                {
                    next_0 = next_1;
                    next_1 = null;
                }
                else
                {
                    minStep = EGameConstL.Infinity;
                    if (opening.Count == 0)
                    {
                        break;
                    }

                    for (int i = opening.Count - 1; i >= 0; --i)
                    {
                        if (!opening[i].open)
                        {
                            opening.RemoveAt(i);
                        }
                        else if (opening[i].F < minStep)
                        {
                            next_0  = opening[i];
                            minStep = next_0.F;
                        }
                        else if (next_1 == null && next_0 != null && opening[i].F == next_0.F)
                        {
                            next_1 = opening[i];
                        }
                    }
                }

                //标志为已关闭
                next_0.open = false;

                //放入已搜索中
                if (searched != null)
                {
                    searched.Add(next_0.thisGrid);
                }

                checkTimes = 6;
                curDir     = lastDir;
                //遍历最近节点的周围6个节点,依次放入close中
                int roads = next_0.thisGrid.NavigationPassable ? 63 : next_0.thisGrid.roadPasses;
                while (checkTimes > 0)
                {
                    //沿着当前探索方向继续探索
                    if ((roads & (1 << curDir)) != 0)
                    {
                        //获取该路通向的下一个item
                        GridUnit sibling = battleMap.GetGridByDir(next_0.thisGrid.row, next_0.thisGrid.column, curDir);
                        if (sibling == null)
                        {
                            //没路
                            ++curDir;
                            curDir = (curDir > 5) ? 0 : curDir;
                            --checkTimes;
                            continue;
                        }
                        //如果这个不能移动
                        else if (sibling.GridType == GridType.Obstacle && !sibling.NavigationPassable)
                        {
                            //没路
                            ++curDir;
                            curDir = (curDir > 5) ? 0 : curDir;
                            --checkTimes;
                            continue;
                        }
                        //如果这个格子有战斗单位且可以战斗
                        else if (sibling.battleUnit != null && sibling.battleUnit.CanAction && !sibling.NavigationPassable)
                        {
                            //无法通过
                            ++curDir;
                            curDir = (curDir > 5) ? 0 : curDir;
                            --checkTimes;
                            continue;
                        }
                        //如果这个item就是目标或者已经进入了停止距离
                        else if ((stopDistance > 0 && sibling.Distance(to) <= stopDistance) || sibling.Equals(to))
                        {
                            catched = true;
                            if (path != null)
                            {
                                path.Add(sibling);

                                NavigationData current = next_0;
                                while (current != null)
                                {
                                    if (current.thisGrid != from)
                                    {
                                        path.Add(current.thisGrid);
                                    }
                                    current = current.preGrid;
                                }
                                //翻转一下
                                path.Reverse();
                            }
                            break;
                        }
                        else
                        {
                            //尝试判断这个是否为closed
                            NavigationData nd = sibling.tempRef == null ? null : (NavigationData)(sibling.tempRef);
                            if (nd == null)
                            {
                                //这个格子没有探索过,新建并添加
                                nd = GetEmptyNavigationData(sibling, next_0, next_0.G + 1, sibling.Distance(to));
                                //这个格子不错哦
                                if (nd.F <= next_0.F && gift == null)
                                {
                                    //保存礼物
                                    gift = nd;
                                    //记录下次起始的更新方向
                                    lastDir = curDir;
                                }
                                //比第二目标好
                                else if (next_1 != null && nd.F < next_1.F)
                                {
                                    //替换第二目标
                                    next_1 = nd;
                                    opening.Add(nd);
                                }
                                else
                                {
                                    //已经设置了礼物,因此只能放入opening列表中,以后再更新了呢
                                    opening.Add(nd);
                                }
                            }
                            else
                            {
                                //只处理没有被探索过的格子
                                if (nd.open)
                                {
                                    //已经在Open列表中了
                                    if ((next_0.G + 1) < nd.G)
                                    {
                                        //比原来的近,应该不可能
                                        nd.G        = next_0.G + 1;
                                        nd.H        = sibling.Distance(to);
                                        nd.F        = nd.G + nd.H;
                                        nd.preGrid  = next_0;
                                        nd.thisGrid = sibling;
                                    }
                                    //这个格子不错哦
                                    if (nd.F <= next_0.F && gift == null)
                                    {
                                        gift = nd;
                                        //保存当前探索方向
                                        lastDir = curDir;
                                    }
                                    else if (next_1 != null && nd.F < next_1.F)
                                    {
                                        //替换第二目标
                                        next_1 = nd;
                                    }
                                }
                            }
                        }
                    }
                    ++curDir;
                    curDir = (curDir > 5) ? 0 : curDir;
                    --checkTimes;
                }
            }

            opening.Clear();

            //重置池子
            ResetPool();

            //有步数限制
            if (catched &&
                path != null &&
                mobility > 0)
            {
                for (int i = 0; i < path.Count; ++i)
                {
                    if (path[i].Distance(from) > mobility)
                    {
                        path.RemoveRange(i, path.Count - i);
                        break;
                    }
                }
            }

            return(catched);
        }
Ejemplo n.º 7
0
 //检查是否在攻击范围
 private bool CheckUnderAttackRadius()
 {
     return(mapGrid.Distance(targetBattleUnit.mapGrid) <= 1);
 }