public SkillChosenMenu(int teamIndex, int skillSlot)
        {
            this.teamIndex = teamIndex;
            this.skillSlot = skillSlot;

            bool shiftUp   = (skillSlot > 0);
            bool shiftDown = (skillSlot < DataManager.Instance.Save.ActiveTeam.Players[teamIndex].Skills.Count - 1) && (DataManager.Instance.Save.ActiveTeam.Players[teamIndex].Skills[skillSlot + 1].Element.SkillNum > -1);

            List <MenuTextChoice> choices = new List <MenuTextChoice>();

            if (GameManager.Instance.CurrentScene == DungeonScene.Instance)
            {
                CharIndex turnChar = ZoneManager.Instance.CurrentMap.CurrentTurnMap.GetCurrentTurnChar();
                if (turnChar.Team == -1 && turnChar.Char == teamIndex)
                {
                    choices.Add(new MenuTextChoice(Text.FormatKey("MENU_SKILL_USE"), useAction));
                }
            }
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_SKILL_SWITCH"), switchAction));
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_SHIFT_UP"), () => { shiftPosition(false); }, shiftUp, shiftUp ? Color.White : Color.Red));
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_SHIFT_DOWN"), () => { shiftPosition(true); }, shiftDown, shiftDown ? Color.White : Color.Red));
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_EXIT"), MenuManager.Instance.RemoveMenu));

            Initialize(new Loc(168, 16), CalculateChoiceLength(choices, 72), choices.ToArray(), 0);
        }
Beispiel #2
0
        public XmlElement ToXML(XmlDocument doc)
        {
            XmlElement elem = doc.CreateElement("funcRef");

            if (Definition != null)
            {
                elem.SetAttribute("sfPath", Definition.SF.SFPath);
                elem.SetAttribute("name", Definition.Name);
            }
            else if (_sfDefinition != null)
            {
                elem.SetAttribute("sfPath", _sfDefinition.SFPath);
                elem.SetAttribute("name", _name);
            }
            else
            {
                throw new InvalidOperationException();
            }

            elem.SetAttribute("charIndex", CharIndex.ToString());
            elem.SetAttribute("charLength", CharLength.ToString());
            elem.SetAttribute("codePart", CodePart);
            elem.SetAttribute("isCall", (Arguments != null).ToString());

            if (Arguments != null)
            {
                foreach (FuncRefArgInfo funcArgRef in Arguments)
                {
                    elem.AppendChild(funcArgRef.ToXML(doc));
                }
            }

            return(elem);
        }
Beispiel #3
0
        public XmlElement ToXML(XmlDocument doc)
        {
            XmlElement elem = doc.CreateElement("usingRef");

            if (Definition != null)
            {
                elem.SetAttribute("sfPath", Definition.SF.SFPath);
                elem.SetAttribute("name", Definition.Name);
            }
            else if (_sfDefinition != null)
            {
                elem.SetAttribute("sfPath", _sfDefinition.SFPath);
                elem.SetAttribute("name", _name);
            }
            else
            {
                throw new InvalidOperationException();
            }

            elem.SetAttribute("charIndex", CharIndex.ToString());
            elem.SetAttribute("charLength", CharLength.ToString());
            elem.SetAttribute("codePart", CodePart);

            return(elem);
        }
Beispiel #4
0
        public XmlElement ToXML(XmlDocument doc)
        {
            XmlElement argElem = doc.CreateElement("funcRefArg");

            argElem.SetAttribute("charIndex", CharIndex.ToString());
            argElem.SetAttribute("charLength", CharLength.ToString());
            return(argElem);
        }
Beispiel #5
0
        public override void Apply(GameEventOwner owner, Character ownerChar, Character character)
        {
            CharIndex charIndex = ZoneManager.Instance.CurrentMap.GetCharIndex(character);

            if (charIndex.Faction == Faction)
            {
                BaseEvent.Apply(owner, ownerChar, character);
            }
        }
Beispiel #6
0
        public TeamMenu(bool sendHome, int teamSlot)
        {
            int menuWidth = 160;

            this.sendHome = sendHome;
            bool checkSkin = DataManager.Instance.Save is RogueProgress && sendHome;

            if (checkSkin && DataManager.Instance.Save.ActiveTeam.Players.Count > ExplorerTeam.MAX_TEAM_SLOTS)
            {
                checkSkin = false;
                foreach (Character character in DataManager.Instance.Save.ActiveTeam.Players)
                {
                    if (!DataManager.Instance.GetSkin(character.BaseForm.Skin).Challenge || character.Dead)
                    {
                        checkSkin = true;
                    }
                }
            }
            List <MenuChoice> team = new List <MenuChoice>();

            foreach (Character character in DataManager.Instance.Save.ActiveTeam.Players)
            {
                int  teamIndex = team.Count;
                bool disabled  = false;
                if (GameManager.Instance.CurrentScene == DungeonScene.Instance)
                {
                    CharIndex turnChar = ZoneManager.Instance.CurrentMap.CurrentTurnMap.GetCurrentTurnChar();
                    if (sendHome && turnChar.Char == team.Count)//disable the current turn choice in send home mode
                    {
                        disabled = true;
                    }
                }
                if (checkSkin)
                {
                    disabled |= DataManager.Instance.GetSkin(character.BaseForm.Skin).Challenge&& !character.Dead;
                }

                MenuText memberName = new MenuText(character.GetDisplayName(true), new Loc(2, 1), disabled ? Color.Red : Color.White);
                MenuText memberLv   = new MenuText(Text.FormatKey("MENU_TEAM_LEVEL_SHORT", character.Level), new Loc(menuWidth - 8 * 4, 1), DirV.Up, DirH.Right, disabled ? Color.Red : Color.White);
                team.Add(new MenuElementChoice(() => { choose(teamIndex); }, !disabled, memberName, memberLv));
            }

            summaryMenu = new TeamMiniSummary(Rect.FromPoints(new Loc(16,
                                                                      GraphicsManager.ScreenHeight - 8 - GraphicsManager.MenuBG.TileHeight * 2 - VERT_SPACE * 5),
                                                              new Loc(GraphicsManager.ScreenWidth - 16, GraphicsManager.ScreenHeight - 8)));

            if (teamSlot == -1)
            {
                teamSlot = Math.Min(Math.Max(0, defaultChoice), team.Count - 1);
            }

            Initialize(new Loc(16, 16), menuWidth, Text.FormatKey("MENU_TEAM_TITLE"), team.ToArray(), teamSlot);
        }
Beispiel #7
0
        public override GameAction Think(Character controlledChar, bool preThink, IRandom rand)
        {
            if (controlledChar.CantWalk)
            {
                return(null);
            }

            Alignment alignment = Alignment.None;

            if (RunFromAllies)
            {
                alignment |= Alignment.Friend;
            }
            if (RunFromFoes)
            {
                alignment |= Alignment.Foe;
            }
            List <Character> seenCharacters = controlledChar.GetSeenCharacters(alignment);

            if (seenCharacters.Count == 0)
            {
                return(null);
            }

            CharIndex ownIndex = ZoneManager.Instance.CurrentMap.GetCharIndex(controlledChar);

            if (RunFromAllies && !RunFromFoes)
            {
                //when running from allies and not enemies, run from only the ones that are higher ranking than this one
                CharIndex seenIndex = ZoneManager.Instance.CurrentMap.GetCharIndex(seenCharacters[0]);
                if (seenIndex.Team > ownIndex.Team || seenIndex.Team == ownIndex.Team && seenIndex.Char > ownIndex.Char) //the lowest index is higher than this, therefore there's no one to run away from
                {
                    return(null);
                }
            }

            return(DumbAvoid(controlledChar, preThink, seenCharacters, ownIndex, rand));
        }
Beispiel #8
0
        public MainMenu()
        {
            bool equippedItems = false;

            foreach (Character character in DataManager.Instance.Save.ActiveTeam.Players)
            {
                if (!character.Dead && character.EquippedItem.ID > -1)
                {
                    equippedItems = true;
                    break;
                }
            }
            bool invEnabled = !(DataManager.Instance.Save.ActiveTeam.GetInvCount() == 0 && !equippedItems);

            List <MenuTextChoice> choices = new List <MenuTextChoice>();

            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_MAIN_SKILLS"), () =>
            {
                int mainIndex = DataManager.Instance.Save.ActiveTeam.LeaderIndex;
                if (GameManager.Instance.CurrentScene == DungeonScene.Instance)
                {
                    CharIndex turnChar = ZoneManager.Instance.CurrentMap.CurrentTurnMap.GetCurrentTurnChar();
                    if (turnChar.Team == -1)
                    {
                        mainIndex = turnChar.Char;
                    }
                }
                MenuManager.Instance.AddMenu(new SkillMenu(mainIndex), false);
            }));
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_MAIN_INVENTORY"), () => { MenuManager.Instance.AddMenu(new ItemMenu(), false); }, invEnabled, invEnabled ? Color.White : Color.Red));

            bool hasTactics = (DataManager.Instance.Save.ActiveTeam.Players.Count > 1);
            bool inReplay   = (DataManager.Instance.CurrentReplay != null);

            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_TACTICS_TITLE"), () => { MenuManager.Instance.AddMenu(new TacticsMenu(), false); }, (hasTactics && !inReplay), (hasTactics && !inReplay) ? Color.White : Color.Red));
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_TEAM_TITLE"), () => { MenuManager.Instance.AddMenu(new TeamMenu(false), false); }));

            if (GameManager.Instance.CurrentScene == DungeonScene.Instance)
            {
                bool hasGround = DungeonScene.Instance.CanCheckGround();
                choices.Add(new MenuTextChoice(Text.FormatKey("MENU_GROUND_TITLE"), checkGround, (hasGround && !inReplay), (hasGround && !inReplay) ? Color.White : Color.Red));
            }

            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_OTHERS_TITLE"), () => { MenuManager.Instance.AddMenu(new OthersMenu(), false); }));
            if (!inReplay)
            {
                if (((GameManager.Instance.CurrentScene == DungeonScene.Instance)) || DataManager.Instance.Save is RogueProgress)
                {
                    choices.Add(new MenuTextChoice(Text.FormatKey("MENU_REST_TITLE"), () => { MenuManager.Instance.AddMenu(new RestMenu(), false); }));
                }
                else
                {
                    choices.Add(new MenuTextChoice(Text.FormatKey("MENU_MAIN_SAVE"), SaveAction));
                }
            }
            else
            {
                choices.Add(new MenuTextChoice(Text.FormatKey("MENU_REPLAY_TITLE"), () => { MenuManager.Instance.AddMenu(new ReplayMenu(), false); }));
            }
            choices.Add(new MenuTextChoice(Text.FormatKey("MENU_EXIT"), MenuManager.Instance.RemoveMenu));

            Initialize(new Loc(16, 16), CalculateChoiceLength(choices, 72), choices.ToArray(), Math.Min(Math.Max(0, defaultChoice), choices.Count - 1));

            titleMenu = new SummaryMenu(Rect.FromPoints(new Loc(Bounds.End.X + 16, 32), new Loc(GraphicsManager.ScreenWidth - 16, 32 + LINE_SPACE + GraphicsManager.MenuBG.TileHeight * 2)));
            MenuText title = new MenuText((GameManager.Instance.CurrentScene == DungeonScene.Instance) ? ZoneManager.Instance.CurrentMap.GetSingleLineName() : ZoneManager.Instance.CurrentGround.GetSingleLineName(),
                                          new Loc((titleMenu.Bounds.X + titleMenu.Bounds.End.X) / 2, titleMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight), DirH.None);

            title.Color = TextTan;
            titleMenu.Elements.Add(title);

            summaryMenu = new SummaryMenu(Rect.FromPoints(new Loc(16, 32 + choices.Count * VERT_SPACE + GraphicsManager.MenuBG.TileHeight * 2),
                                                          new Loc(GraphicsManager.ScreenWidth - 16, GraphicsManager.ScreenHeight - 8)));
            summaryMenu.Elements.Add(new MenuText(Text.FormatKey("MENU_BAG_MONEY", Text.FormatKey("MONEY_AMOUNT", DataManager.Instance.Save.ActiveTeam.Money)),
                                                  new Loc(summaryMenu.Bounds.X + GraphicsManager.MenuBG.TileWidth + 8, summaryMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight)));

            if (GameManager.Instance.CurrentScene == DungeonScene.Instance)
            {
                string weather = DataManager.Instance.GetMapStatus(0).Name.ToLocal();
                foreach (MapStatus status in ZoneManager.Instance.CurrentMap.Status.Values)
                {
                    if (status.StatusStates.Contains <MapWeatherState>())
                    {
                        MapStatusData entry = (MapStatusData)status.GetData();
                        weather = entry.Name.ToLocal();
                        break;
                    }
                }
                summaryMenu.Elements.Add(new MenuText(Text.FormatKey("MENU_MAP_CONDITION", weather),
                                                      new Loc(GraphicsManager.ScreenWidth / 2, summaryMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight)));
            }

            int level_length  = GraphicsManager.TextFont.SubstringWidth(Text.FormatKey("MENU_TEAM_LEVEL_SHORT", DataManager.Instance.MaxLevel));
            int hp_length     = GraphicsManager.TextFont.SubstringWidth(Text.FormatKey("MENU_TEAM_HP", 999, 999));
            int hunger_length = GraphicsManager.TextFont.SubstringWidth(Text.FormatKey("MENU_TEAM_HUNGER", Character.MAX_FULLNESS, Character.MAX_FULLNESS));

            int remaining_width = summaryMenu.Bounds.End.X - summaryMenu.Bounds.X - (GraphicsManager.MenuBG.TileWidth + 4) * 2 - level_length - hp_length - hunger_length - NicknameMenu.MAX_LENGTH;

            for (int ii = 0; ii < DataManager.Instance.Save.ActiveTeam.Players.Count; ii++)
            {
                Character character  = DataManager.Instance.Save.ActiveTeam.Players[ii];
                int       text_start = summaryMenu.Bounds.X + GraphicsManager.MenuBG.TileWidth + 4;
                summaryMenu.Elements.Add(new MenuText(character.BaseName,
                                                      new Loc(text_start, summaryMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight + (ii + 1) * LINE_SPACE)));
                text_start += NicknameMenu.MAX_LENGTH + remaining_width / 3;
                summaryMenu.Elements.Add(new MenuText(Text.FormatKey("MENU_TEAM_LEVEL_SHORT", character.Level),
                                                      new Loc(text_start + level_length / 2, summaryMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight + (ii + 1) * LINE_SPACE), DirH.None));
                text_start += level_length + remaining_width / 3;
                summaryMenu.Elements.Add(new MenuText(Text.FormatKey("MENU_TEAM_HP", character.HP, character.MaxHP),
                                                      new Loc(text_start + hp_length / 2, summaryMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight + (ii + 1) * LINE_SPACE), DirH.None));
                text_start += hp_length + remaining_width / 3;
                summaryMenu.Elements.Add(new MenuText(Text.FormatKey("MENU_TEAM_HUNGER", character.Fullness, character.MaxFullness),
                                                      new Loc(text_start + hunger_length / 2, summaryMenu.Bounds.Y + GraphicsManager.MenuBG.TileHeight + (ii + 1) * LINE_SPACE), DirH.None));
            }
        }
Beispiel #9
0
        static void Main(string[] args)
        {
            string inp = Console.ReadLine();

            CharIndex[] charIndex = new CharIndex[inp.Length];
            for (int i = 0; i < inp.Length; i++)
            {
                charIndex[i].ch    = inp[i];
                charIndex[i].index = i;
            }
            List <int>        index = new List <int>();
            Stack <CharIndex> stack = new Stack <CharIndex>();

            for (int i = 0; i < inp.Length; i++)
            {
                if (inp[i] == '(')
                {
                    CharIndex temp = new CharIndex {
                        ch    = '(',
                        index = i
                    };
                    stack.Push(temp);
                }
                if (inp[i] == ')')
                {
                    if (stack.Count > 0)
                    {
                        if (stack.Peek().ch == '(')
                        {
                            stack.Pop();
                        }
                        else
                        {
                            index.Add(i);
                        }
                    }
                    else
                    {
                        index.Add(i);
                    }
                }
            }

            while (stack.Count != 0)
            {
                index.Add(stack.Peek().index);
                stack.Pop();
            }
            string res = "";

            if (index.Count != 0)
            {
                for (int i = 0; i < inp.Length; i++)
                {
                    for (int j = 0; j < index.Count; j++)
                    {
                        if (i != index[j])
                        {
                            res += inp[i];
                        }
                    }
                }
            }
            else
            {
                res = inp;
            }
            Console.WriteLine(res);
            Console.ReadLine();
        }
Beispiel #10
0
        public static int[] SearchString(this string text, string pattern)
        {
            //Список позиций вхождения подстроки в тексте (все индексы, где шаблон был найден в тексте, т.е. результаты поиска)
            List <int> positions = new List <int>();

            _lastFoundTable.Clear();

            //Вычислим длину шаблона (исключительно ради удобства)
            int pl = pattern.Length - 1; //pl = Pattern Lenght

            //Вычисляем индексы последнего вхождения каждого символа искомой строки и загоняем всё это в таблицу
            int i = pl;

            foreach (var ch in pattern)
            {
                if (_lastFoundTable.ContainsKey(ch))
                {
                    _lastFoundTable[ch].LastIndex = i; //Обновляем индекс символа
                }
                else
                {
                    _lastFoundTable.Add(ch, new CharIndex {
                        Letter = ch, LastIndex = i
                    });                                                                    //Такого символа еще не было -> добавляем.
                }
                i--;
            }

            //Можно было бы вновь длину шаблона обозвать за i, но что бы не путаться, пусть будет так:
            int j = pl;

            //А теперь основной цикл поиска по всему тексту
            while (j <= text.Length - 1)
            {
                var patternLastChar = pattern[pl];

                if (text[j] != patternLastChar)
                {
                    //Аналитика 1
                    //Если у нас последний символ текста не совпадает с последним символом шаблона, и этот символ отсутствует в шаблоне,
                    //тогда сдвигаем указатель на длину поискового шаблона:
                    if (!_lastFoundTable.ContainsKey(text[j]))
                    {
                        j += pl;
                    }

                    //Аналитика 2
                    //Смотрим нашу таблицу с индексами на предмет получения индекса последнего вхождения текущего символа в тексте
                    //и двигаем указатель к этому индексу.
                    if (j <= text.Length - 1 && _lastFoundTable.ContainsKey(text[j]))
                    {
                        CharIndex tmp = _lastFoundTable[text[j]];
                        if (tmp != null)
                        {
                            j += tmp.LastIndex;
                        }
                    }
                }

                int k = pl; //Длина шаблона - 1
                int m = j;  //Указатель теперь в m
                if (j <= text.Length - 1)
                {
                    while (k >= 0)
                    {
                        //Аналитика 3.1.
                        //Сравним символ из текста с символом шаблона в обратном порядке. Если они совпадают, то выполним проверку, а не закончился ли у нас шаблон?
                        //Если шаблон у нас закончился (все его символы просмотрели), то, учтоним, если указатель m + длина шаблона не выходят за границы текста, то мы нашли совпадение!
                        //в этом случае сдвигаемся влево на длину шаблона. Ну и запоминаем позицию вхождения.
                        if (text[m] == pattern[k])
                        {
                            if (k == 0 && text[m] == pattern[k])
                            {
                                if (m + pattern.Length <= text.Length)
                                {
                                    positions.Add(m);
                                }
                                j += pl;
                            }
                            m--; k--;
                            continue;
                        }

                        if (!_lastFoundTable.ContainsKey(text[m]))
                        {
                            //Аналитика 3.2
                            //Если у нас встретился символ в тексте, который не содержится в шаблоне, то мы сдвигем указатель на величину
                            //к индексу этого несовпадающего символа + число совпадающих символов.,
                            j += k + (j - m);
                            break;
                        }
                        k--;
                    }
                }
                j++;
            }

            //Подготовка и возврат результата:
            if (positions.Count == 0)
            {
                positions.Add(-1);
            }
            return(positions.ToArray());
        }
Beispiel #11
0
        private GameAction SmartAvoid(Character controlledChar, bool preThink, List <Character> seenCharacters, CharIndex ownIndex, ReRandom rand)
        {
            StablePriorityQueue <double, Dir8> candidateDirs = new StablePriorityQueue <double, Dir8>();

            //use djikstra to find a path out
            //choose the path that avoids other characters the most


            //remove all locs from the locHistory that are no longer on screen
            Loc seen = Character.GetSightDims();

            for (int ii = locHistory.Count - 1; ii >= 0; ii--)
            {
                Loc diff = locHistory[ii] - controlledChar.CharLoc;
                if (Math.Abs(diff.X) > seen.X || Math.Abs(diff.Y) > seen.Y || ii > 15)
                {
                    locHistory.RemoveRange(0, ii);
                    break;
                }
            }
            Loc offset = controlledChar.CharLoc - seen;

            //CHECK FOR ADVANCE
            if (goalPath.Count > 1 && goalPath[goalPath.Count - 2] == controlledChar.CharLoc) //check if we advanced since last time
            {
                goalPath.RemoveAt(goalPath.Count - 1);                                        //remove our previous trail
            }
            //check to see if the end loc is still valid... or, just check to see if *the next step* is still valid
            if (goalPath.Count > 1)
            {
                if (controlledChar.CharLoc == goalPath[goalPath.Count - 1])//check if on the trail
                {
                    if (!ZoneManager.Instance.CurrentMap.TileBlocked(goalPath[goalPath.Count - 2], controlledChar.Mobility) &&
                        !BlockedByTrap(controlledChar, goalPath[goalPath.Count - 2]) &&
                        !BlockedByHazard(controlledChar, goalPath[goalPath.Count - 2]))//check to make sure the next step didn't suddely become blocked
                    {
                        //update current traversals
                        if (locHistory.Count == 0 || locHistory[locHistory.Count - 1] != controlledChar.CharLoc)
                        {
                            locHistory.Add(controlledChar.CharLoc);
                        }
                        if (!preThink)
                        {
                            Character destChar = ZoneManager.Instance.CurrentMap.GetCharAtLoc(goalPath[goalPath.Count - 2]);
                            if (destChar != null && ZoneManager.Instance.CurrentMap.TerrainBlocked(controlledChar.CharLoc, destChar.Mobility))
                            {
                                return(new GameAction(GameAction.ActionType.Wait, Dir8.None));
                            }
                        }
                        GameAction act = TrySelectWalk(controlledChar, DirExt.GetDir(goalPath[goalPath.Count - 1], goalPath[goalPath.Count - 2]));
                        //attempt to continue the path
                        //however, we can only verify that we continued on the path on the next loop, using the CHECK FOR ADVANCE block
                        return(act);
                    }
                }
            }

            //if it isn't find a new end loc
            List <Loc> seenExits = GetAreaExits(controlledChar);

            if (seenExits.Count == 0)
            {
                return(null);
            }
            //one element in the acceptable range will be randomly selected to be the one that drives the heuristic

            //later, rate the exits based on how far they are from the tail point of the lochistory
            //add them to a sorted list

            List <Loc> forwardFacingLocs = new List <Loc>();

            if (locHistory.Count > 0)
            {
                List <int> forwardFacingIndices = new List <int>();
                Loc        pastDir = locHistory[0] - controlledChar.CharLoc;
                for (int ii = 0; ii < seenExits.Count; ii++)
                {
                    if (Loc.Dot(pastDir, (seenExits[ii] - controlledChar.CharLoc)) <= 0)
                    {
                        forwardFacingLocs.Add(seenExits[ii]);
                        seenExits.RemoveAt(ii);
                    }
                }
            }

            //if any of the tiles are reached in the search, they will be automatically chosen

            //Analysis:
            //if there is only one exit, and it's easily reached, the speed is the same - #1 fastest case
            //if there are many exits, and they're easily reached, the speed is the same - #1 fastest case
            //if there's one exit, and it's impossible, the speed is the same - #2 fastest case
            //if there's many exits, and they're all impossible, the speed is faster - #2 fastest case
            //if there's many exits, and only the backtrack is possible, the speed is faster - #2 fastest case

            if (forwardFacingLocs.Count > 0)
            {
                goalPath = GetRandomPathPermissive(rand, controlledChar, forwardFacingLocs);
            }

            //then attempt remaining locations
            if (goalPath.Count == 0)
            {
                goalPath = GetRandomPathPermissive(rand, controlledChar, seenExits);
            }

            if (goalPath.Count == 0)
            {
                return(null);
            }

            if (locHistory.Count == 0 || locHistory[locHistory.Count - 1] != controlledChar.CharLoc)
            {
                locHistory.Add(controlledChar.CharLoc);
            }

            //TODO: we seldom ever run into other characters who obstruct our path, but if they do, try to wait courteously for them if they are earlier on the team list than us
            //check to make sure we aren't force-warping anyone from their position
            if (!preThink && goalPath.Count > 1)
            {
                Character destChar = ZoneManager.Instance.CurrentMap.GetCharAtLoc(goalPath[goalPath.Count - 2]);
                if (destChar != null && ZoneManager.Instance.CurrentMap.TerrainBlocked(controlledChar.CharLoc, destChar.Mobility))
                {
                    return(new GameAction(GameAction.ActionType.Wait, Dir8.None));
                }
            }
            return(SelectChoiceFromPath(controlledChar, goalPath));
        }
Beispiel #12
0
        private GameAction DumbAvoid(Character controlledChar, bool preThink, List <Character> seenCharacters, CharIndex ownIndex, IRandom rand)
        {
            StablePriorityQueue <double, Dir8> candidateDirs = new StablePriorityQueue <double, Dir8>();

            //choose the single direction that avoids other characters the most
            bool respectPeers = !preThink;

            for (int ii = -1; ii < DirExt.DIR8_COUNT; ii++)
            {
                Loc checkLoc = controlledChar.CharLoc + ((Dir8)ii).GetLoc();

                double dirDistance = 0;
                //iterated in increasing character indices
                foreach (Character seenChar in seenCharacters)
                {
                    if (RunFromAllies && !RunFromFoes)
                    {
                        //only avoid if their character index is lower than this one, aka higher ranking member
                        CharIndex seenIndex = ZoneManager.Instance.CurrentMap.GetCharIndex(seenChar);
                        if (seenIndex.Team > ownIndex.Team)
                        {
                            break;
                        }
                        else if (seenIndex.Team == ownIndex.Team)
                        {
                            if (seenIndex.Char > ownIndex.Char && seenChar.MemberTeam.LeaderIndex != seenIndex.Char)
                            {
                                continue;
                            }
                        }
                    }

                    dirDistance += Math.Sqrt((checkLoc - seenChar.CharLoc).DistSquared());
                }

                candidateDirs.Enqueue(-dirDistance, (Dir8)ii);
            }


            Grid.LocTest checkDiagBlock = (Loc testLoc) =>
            {
                return(ZoneManager.Instance.CurrentMap.TileBlocked(testLoc, controlledChar.Mobility, true));
                //enemy/ally blockings don't matter for diagonals
            };

            Grid.LocTest checkBlock = (Loc testLoc) =>
            {
                if (ZoneManager.Instance.CurrentMap.TileBlocked(testLoc, controlledChar.Mobility))
                {
                    return(true);
                }

                if ((IQ & AIFlags.TrapAvoider) != AIFlags.None)
                {
                    Tile tile = ZoneManager.Instance.CurrentMap.Tiles[testLoc.X][testLoc.Y];
                    if (tile.Effect.ID > -1)
                    {
                        TileData entry = DataManager.Instance.GetTile(tile.Effect.ID);
                        if (entry.StepType == TileData.TriggerType.Trap || entry.StepType == TileData.TriggerType.Site || entry.StepType == TileData.TriggerType.Switch)
                        {
                            return(true);
                        }
                    }
                }

                if (respectPeers && BlockedByChar(testLoc, Alignment.Self | Alignment.Foe))
                {
                    return(true);
                }

                return(false);
            };

            //try each direction from most appealing to least appealing, stopping if we get to "none"
            while (candidateDirs.Count > 0)
            {
                Dir8 highestDir = candidateDirs.Dequeue();
                if (highestDir == Dir8.None)
                {
                    if (AbortIfCornered)//this plan will be aborted, try the next plan in the list
                    {
                        return(null);
                    }
                    else//cry in a corner
                    {
                        return(new GameAction(GameAction.ActionType.Wait, Dir8.None));
                    }
                }
                else
                {
                    //check to see if we can walk this way
                    if (!Grid.IsDirBlocked(controlledChar.CharLoc, highestDir, checkBlock, checkDiagBlock))
                    {
                        return(TrySelectWalk(controlledChar, highestDir));
                    }
                }
            }

            if (AbortIfCornered)//this plan will be aborted, try the next plan in the list
            {
                return(null);
            }
            else//cry in a corner
            {
                return(new GameAction(GameAction.ActionType.Wait, Dir8.None));
            }
        }