示例#1
0
        private void AddSkillCommands(ref List <string> commands, Game_Unit unit)
        {
            // Actions:
            //   100 = Shelter
            //   101 = Dash
            //   102 = Swoop
            //   103 = Trample
            //   104 = Sacrifice
            //   105 = Refuge
            //   120 = Old Swoop //Debug
            if (CantoAllowsNormalActions(Canto))
            {
                // Skills: Savior
                if (commands.Contains("Rescue") && unit.has_cover() &&
                    !unit.is_rescue_blocked())
                {
                    List <int> allyRange = unit.allies_in_range(1);
                    bool       canRescue = false;
                    foreach (int id in allyRange)
                    {
                        if (unit.can_rescue(Global.game_map.units[id]))
                        {
                            if (Pathfind.passable(unit, Global.game_map.units[id].loc))
                            {
                                canRescue = true;
                                break;
                            }
                        }
                    }
                    if (canRescue)
                    {
                        int index = commands.IndexOf("Rescue");
                        commands.Insert(index + 1, "Shelter");
                        AddSkillIndex(index, SkillMenuIds.Shelter);
                    }
                }
                {
                    List <int> allyRange     = unit.allies_in_range(1);
                    bool       canTakeRefuge = false;
                    foreach (int id in allyRange)
                    {
                        Game_Unit target = Global.game_map.units[id];
                        if (target.has_refuge() && target.can_rescue(unit) &&
                            !unit.is_rescue_blocked())
                        {
                            canTakeRefuge = true;
                            break;
                        }
                    }
                    if (canTakeRefuge)
                    {
                        // Place before status and wait, at least
                        int index = Math.Min(
                            commands.IndexOf("Status"), commands.IndexOf("Wait"));

                        // Try placing before Item
                        int itemIndex = commands.IndexOf("Item");
                        if (itemIndex >= 0)
                        {
                            index = itemIndex;
                        }
                        // Try placing after rescue
                        int rescueIndex = commands.IndexOf("Rescue");
                        if (rescueIndex >= 0)
                        {
                            index = rescueIndex + 1;
                        }
                        // Try placing after shelter
                        int shelterIndex = commands.IndexOf("Shelter");
                        if (shelterIndex >= 0)
                        {
                            index = shelterIndex + 1;
                        }

                        commands.Insert(index + 0, "Refuge");
                        AddSkillIndex(index - 1, SkillMenuIds.Refuge);
                    }
                }
                // Skills: Dash
                if (unit.actor.has_skill("DASH"))
                {
                    // Can move and not in starting location/has done something
                    if (unit.base_mov > 0 && (unit.turn_start_loc != unit.loc ||
                                              Canto != Canto_Records.None))
                    {
                        int index = Math.Min(
                            commands.IndexOf("Status"), commands.IndexOf("Wait"));
                        commands.Insert(index + 0, "Dash");
                        AddSkillIndex(index - 1, SkillMenuIds.Dash);
                    }
                }
                // Skills: Swoop
                if (unit.actor.has_skill("SWOOP"))
                {
                    List <int>[] ary        = unit.enemies_in_swoop_range();
                    List <int>   enemyRange = ary[0];
                    if (enemyRange.Count > 0)
                    {
                        Global.game_temp.temp_skill_ranges["SWOOP"] = unit.swoop_range();
                        Global.game_map.range_start_timer           = 0;
                        int index = commands.IndexOf("Attack");
                        commands.Insert(index + 1, "Swoop");
                        AddSkillIndex(index, SkillMenuIds.Swoop);
                    }
                }
                // Skills: Trample
                if (unit.actor.has_skill("TRAMPLE"))
                {
                    List <int>[] ary        = unit.enemies_in_trample_range();
                    List <int>   enemyRange = ary[0];
                    if (enemyRange.Count > 0)
                    {
                        Global.game_temp.temp_skill_ranges["TRAMPLE"]      = unit.trample_range();
                        Global.game_temp.temp_skill_move_ranges["TRAMPLE"] = unit.trample_move_range();
                        Global.game_map.range_start_timer = 0;
                        int index = commands.IndexOf("Attack");
                        commands.Insert(index + 1, "Trample");
                        AddSkillIndex(index, SkillMenuIds.Trample);
                    }
                }
                // Skills: Sacrifice
                if (unit.actor.has_skill("SACRIFICE"))
                {
                    if (unit.actor.hp > 1)
                    {
                        List <int> allyRange = unit.allies_in_range(1);
                        bool       canHeal   = false;
                        foreach (int id in allyRange)
                        {
                            if (!Global.game_map.units[id].actor.is_full_hp())
                            {
                                canHeal = true;
                                break;
                            }
                        }
                        if (canHeal)
                        {
                            int index = commands.IndexOf("Attack");
                            commands.Insert(index + 1, "Sacrifice");
                            AddSkillIndex(index, SkillMenuIds.Sacrifice);
                        }
                    }
                }
                // Skills: Old Swoop //@Debug
                if (unit.actor.has_skill("OLDSWOOP"))
                {
                    List <int>[] ary        = unit.enemies_in_old_swoop_range();
                    List <int>   enemyRange = ary[0];
                    if (enemyRange.Count > 0)
                    {
                        Global.game_temp.temp_skill_ranges["OLDSWOOP"] = unit.old_swoop_range();
                        Global.game_map.range_start_timer = 0;
                        int index = commands.IndexOf("Attack");
                        commands.Insert(index + 1, "OldSwoop");
                        AddSkillIndex(index, SkillMenuIds.OldSwoop);
                    }
                }
                // Skills: Masteries
                for (int i = 0; i < Game_Unit.MASTERIES.Count; i++)
                {
                    if (unit.actor.has_skill(Game_Unit.MASTERIES[i]) && unit.is_mastery_ready(Game_Unit.MASTERIES[i]))
                    {
                        string       skill    = Game_Unit.MASTERIES[i];
                        List <int>[] rangeAry = unit.enemies_in_range(skill);
                        if (rangeAry[1].Count > 0)
                        {
                            List <int> itemIndices = unit.weapon_indices(rangeAry[1]);
                            Global.game_temp.temp_skill_ranges[skill] = unit.get_weapon_range(itemIndices, new HashSet <Vector2> {
                                unit.loc
                            }, skill);

                            //Global.game_temp.temp_skill_ranges[skill] = Global.game_map.get_unit_range(new List<Vector2> { unit.loc },
                            //    unit.min_range_absolute(skill), unit.max_range_absolute(skill), Game_Unit.mastery_blocked_through_walls(skill));
                            Global.game_map.range_start_timer = 0;

                            int index = commands.IndexOf("Attack");
                            commands.Insert(index + 1, Global.skill_from_abstract(skill).Name);
                            IndexRedirect.Insert(index + 1, BASE_MASTERY_MENU_ID + i);
                        }
                    }
                }
            }
        }
        protected List <int> get_targets()
        {
            Game_Unit  unit         = get_unit();
            List <int> temp_targets = new List <int>();

            switch (Mode)
            {
            // Looking for people to rescue
            case 0:
                List <int> rescue_targets = unit.allies_in_range(1);
                foreach (int id in rescue_targets)
                {
                    if (unit.can_rescue(Global.game_map.units[id]))
                    {
                        temp_targets.Add(id);
                    }
                }
                break;

            // Looking for drop locations
            case 1:
                foreach (Vector2 loc in unit.drop_locs())
                {
                    temp_targets.Add((int)(loc.X + loc.Y * Global.game_map.width));
                }

                /*foreach (Vector2 loc in new Vector2[] { new Vector2(0, 1), new Vector2(0, -1), new Vector2(1, 0), new Vector2(-1, 0) }) //Debug
                 *  if (!Global.game_map.is_off_map(loc + unit.loc))
                 *      if (!Global.game_map.is_blocked(loc + unit.loc, unit.rescuing))
                 *          if (Pathfinding.passable(Global.game_map.units[unit.rescuing], loc + unit.loc))
                 *              temp_targets.Add((int)((loc + unit.loc).X + (loc + unit.loc).Y * Global.game_map.width));*/
                break;

            // Looking for people to take
            case 2:
                List <int> take_targets = unit.allies_in_range(1);
                foreach (int id in take_targets)
                {
                    if (Global.game_map.units[id].different_team(unit))
                    {
                        continue;
                    }
                    if (!Global.game_map.units[id].is_rescuing)
                    {
                        continue;
                    }
                    if (unit.can_rescue(Global.game_map.units[Global.game_map.units[id].rescuing]))
                    {
                        temp_targets.Add(id);
                    }
                }
                break;

            // Looking for people to give to
            case 3:
                List <int> give_targets = unit.allies_in_range(1);
                foreach (int id in give_targets)
                {
                    if (Global.game_map.units[id].different_team(unit))
                    {
                        continue;
                    }
                    if (Global.game_map.units[id].is_rescuing)
                    {
                        continue;
                    }
                    if (!Global.game_map.units[id].is_rescue_blocked() &&
                        Global.game_map.units[id].can_rescue(Global.game_map.units[unit.rescuing]))
                    {
                        temp_targets.Add(id);
                    }
                }
                break;

            // Skills: Savior
            // Looking for people to cover
            case 4:
                List <int> cover_targets = unit.allies_in_range(1);
                foreach (int id in cover_targets)
                {
                    if (unit.can_rescue(Global.game_map.units[id]))
                    {
                        if (Pathfind.passable(unit, Global.game_map.units[id].loc))
                        {
                            temp_targets.Add(id);
                        }
                    }
                }
                break;

            // Looking for people to take refuge under
            case 5:
                List <int> refuge_targets = unit.allies_in_range(1);
                foreach (int id in refuge_targets)
                {
                    Game_Unit target = Global.game_map.units[id];
                    if (target.has_refuge() && target.can_rescue(unit))
                    {
                        temp_targets.Add(id);
                    }
                }
                break;
            }
            return(temp_targets);
        }
示例#3
0
        private List <string> SetCommands(Canto_Records canto)
        {
            Disabled = new List <int>();
            List <string> commands = new List <string>();

            // Actions:
            //   0 = Attack
            //   1 = Staff
            //   2 = Drop/Rescue
            //   3 = Item
            //   4 = Trade
            //   5 = Wait
            //   6 = Give/Take
            //   7 = Visit
            //   8 = Talk
            //   9 = Shop/Armory
            //  10 = Arena
            //  11 = Chest
            //  12 = Door
            //  13 = Steal
            //  14 = Seize
            //  15 = Status
            //  16 = Dance
            //  17 = Support
            //  18 = Supply
            //  19 = Escape
            //  20 = Construct
            //  29 = Secret Shop/Armory
            //  30 = Arena
            IndexRedirect = new List <int>();
            Game_Unit unit = Global.game_map.units[UnitId];

            unit.actor.remove_broken_items();

            Canto = Canto_Records.None;
            // If canto state is null but the unit is cantoing, set to horse canto
            if (canto == Canto_Records.None && Canto == Canto_Records.None)
            {
                //Canto = (unit.cantoing && unit.has_canto() ? Canto_Records.Horse : Canto_Records.None); //@Debug
                Canto = (unit.cantoing ? Canto_Records.Horse : Canto_Records.None);
            }
            else if (canto != Canto_Records.None)
            {
                Canto = canto;
            }

            if (CantoAllowsNormalActions(Canto))
            {
                List <int>[] range_ary;
                // enemies: attack
                range_ary = unit.enemies_in_range();
                List <int> enemy_range = range_ary[0];
                UseableWeapons = range_ary[1];
                // enemies: staves
                UseableStaves = new List <int>();
                range_ary     = unit.enemies_in_staff_range();
                UseableStaves.AddRange(range_ary[1]);
                // allies: staves
                range_ary = unit.allies_in_staff_range();
                UseableStaves.AddRange(range_ary[1]);
                // other: staves
                range_ary = unit.untargeted_staff_range();
                List <int> other_staff_range = range_ary[0];
                UseableStaves.AddRange(range_ary[1]);
                UseableStaves = UseableStaves.Distinct().ToList();
                // allies
                List <int> ally_range = unit.allies_in_range(1);
                // Attack
                if (UseableWeapons.Count > 0)
                {
                    List <int> item_indices = unit.weapon_indices(UseableWeapons);
                    Global.game_temp.temp_attack_range = unit.get_weapon_range(item_indices, new HashSet <Vector2> {
                        unit.loc
                    });
                    //Global.game_temp.temp_attack_range = Global.game_map.get_unit_range(new List<Vector2> { unit.loc },
                    //    unit.min_range_absolute(), unit.max_range_absolute()); // this should care about the exact weapons, I think //Yeti
                    Global.game_map.range_start_timer = 0;
                    commands.Add("Attack");
                    IndexRedirect.Add(0);
                }
                // Staff
                if (UseableStaves.Count > 0)
                {
                    List <int> item_indices = unit.weapon_indices(UseableStaves);
                    Global.game_temp.temp_staff_range = unit.get_weapon_range(item_indices, new HashSet <Vector2> {
                        unit.loc
                    });
                    //Global.game_temp.temp_staff_range = Global.game_map.get_unit_range(new List<Vector2> { unit.loc },
                    //    unit.min_range_absolute(true), unit.max_range_absolute(true)); // this should care about the exact weapons, I think //Yeti
                    Global.game_map.range_start_timer = 0;
                    commands.Add("Staff");
                    IndexRedirect.Add(1);
                }
                // Seize
                if (Global.game_map.get_seize_points(unit.team, unit.group).Contains(unit.loc) && unit.can_seize)
                {
                    commands.Add("Seize");
                    IndexRedirect.Add(14);
                }
                // Escape
                if (Global.game_map.escape_point_locations(unit.team, unit.group).Contains(unit.loc))
                {
                    var escapePoint = Global.game_map.escape_point_data(unit, unit.loc);
                    if (!escapePoint.LordOnly || unit.can_seize)
                    {
                        commands.Add("Escape");
                        IndexRedirect.Add(19);
                    }
                }
                // Dance
                if (unit.can_dance())
                {
                    if (unit.dance_targets().Count > 0)
                    {
                        commands.Add(unit.dance_name());
                        IndexRedirect.Add(16);
                    }
                }
                // Construct
                bool can_construct = false;
                if (unit.can_assemble() && unit.assemble_targets().Count > 0)
                {
                    can_construct = true;
                }
                if (unit.can_reload() && unit.reload_targets().Count > 0)
                {
                    can_construct = true;
                }
                if (unit.can_reclaim() && unit.reclaim_targets().Count > 0)
                {
                    can_construct = true;
                }
                if (can_construct)
                {
                    commands.Add("Construct");
                    IndexRedirect.Add(20);
                }
                // Steal
                if (unit.can_steal())
                {
                    if (unit.steal_targets().Count > 0)
                    {
                        commands.Add("Steal");
                        IndexRedirect.Add(13);
                        if (unit.actor.is_full_items)
                        {
                            Disabled.Add(13);
                        }
                    }
                }
                // Support
                if (unit.can_support())
                {
                    commands.Add("Support");
                    IndexRedirect.Add(17);
                }
                // Talk
                if (!Canto.HasEnumFlag(Canto_Records.Talk) && unit.can_talk())
                {
                    Global.game_temp.temp_talk_range.Clear();
                    foreach (int id in unit.talk_targets())
                    {
                        Global.game_temp.temp_talk_range.Add(Global.game_map.units[id].loc);
                    }
                    Global.game_map.range_start_timer = 0;
                    commands.Add("Talk");
                    IndexRedirect.Add(8);
                }
                // Visit
                if (unit.can_visit())
                {
                    string visit_name = Global.game_map.visit_locations[unit.loc].Name;
                    commands.Add(!string.IsNullOrEmpty(visit_name) ? visit_name : "Visit");
                    IndexRedirect.Add(7);
                }
                // Chest
                if (unit.can_open_chest(true))
                {
                    if (Global.game_map.chest_locations.ContainsKey(unit.loc))
                    {
                        commands.Add("Chest");
                        IndexRedirect.Add(11);
                    }
                }
                // Door
                if (unit.can_open_door(true))
                {
                    if (unit.door_targets().Count > 0)
                    {
                        commands.Add("Door");
                        IndexRedirect.Add(12);
                    }
                }
                // Shop/arena
                if (Global.game_map.shops.ContainsKey(unit.loc))
                {
                    // Shop
                    if (!Global.game_map.shops[unit.loc].arena)
                    {
                        commands.Add(Global.game_map.shops[unit.loc].face.Split('-')[0]);
                        IndexRedirect.Add(9);
                    }
                    // Arena
                    else
                    if (unit.actor.can_arena())
                    {
                        commands.Add(Global.game_map.shops[unit.loc].face.Split('-')[0]);
                        IndexRedirect.Add(10);
                    }
                }
                // Secret shop/arena
                if (Global.game_map.secret_shops.ContainsKey(unit.loc) && unit.is_member())
                {
                    // Secret Shop
                    if (!Global.game_map.secret_shops[unit.loc].arena)
                    {
                        commands.Add(Global.game_map.secret_shops[unit.loc].face.Split('-')[0]);
                        IndexRedirect.Add(29);
                    }
                    // Secret Arena
                    else
                    if (unit.actor.can_arena())
                    {
                        commands.Add(Global.game_map.secret_shops[unit.loc].face.Split('-')[0]);
                        IndexRedirect.Add(30);
                    }
                }
                // Rescue/Take/Give/Drop
                if (Canto == Canto_Records.None ||
                    (!Canto.HasEnumFlag(Canto_Records.Give) && !Canto.HasEnumFlag(Canto_Records.Take)))
                {
                    if (unit.is_rescuing)
                    {
                        if (unit.can_drop())
                        {
                            commands.Add("Drop");
                            IndexRedirect.Add(2);
                        }
                        // Give
                        bool can_give = false;
                        foreach (int id in ally_range)
                        {
                            if (Global.game_map.units[id].different_team(unit))
                            {
                                continue;
                            }
                            if (Global.game_map.units[id].is_rescuing)
                            {
                                continue;
                            }
                            if (!Global.game_map.units[id].is_rescue_blocked() &&
                                Global.game_map.units[id].can_rescue(Global.game_map.units[unit.rescuing]))
                            {
                                can_give = true;
                            }
                        }
                        if (can_give)
                        {
                            commands.Add("Give");
                            IndexRedirect.Add(6);
                        }
                    }
                    else if (ally_range.Count > 0)
                    {
                        // Rescue/Take
                        bool can_rescue = false, can_take = false;
                        foreach (int id in ally_range)
                        {
                            if (unit.can_rescue(Global.game_map.units[id]))
                            {
                                can_rescue = true;
                            }

                            // Prevent taking from other teams
                            if (Global.game_map.units[id].different_team(unit))
                            {
                                continue;
                            }
                            if (Global.game_map.units[id].is_rescuing)
                            {
                                if (unit.can_rescue(Global.game_map.units[Global.game_map.units[id].rescuing]))
                                {
                                    can_take = true;
                                }
                            }
                        }
                        if (can_rescue)
                        {
                            commands.Add("Rescue");
                            IndexRedirect.Add(2);
                            if (unit.is_rescue_blocked())
                            {
                                Disabled.Add(2);
                            }
                        }
                        if (can_take)
                        {
                            commands.Add("Take");
                            IndexRedirect.Add(6);
                            if (unit.is_rescue_blocked())
                            {
                                Disabled.Add(6);
                            }
                        }
                    }
                }
            }
            // Item
            if (CantoAllowsItem(Canto))
            {
                if (unit.actor.has_items)
                {
                    commands.Add("Item");
                    IndexRedirect.Add(3);
                }
            }
            // Trade
            if (CantoAllowsTrade(Canto))
            {
                if (unit.can_trade)
                {
                    commands.Add("Trade");
                    IndexRedirect.Add(4);
                }
            }
            else if (CantoAllowsTakeDrop(Canto))
            {
                if (unit.can_drop())
                {
                    commands.Add("Drop");
                    IndexRedirect.Add(2);
                }
            }
            if (!ContinuousMoveCanto(Canto) && !Canto.HasEnumFlag(Canto_Records.Supply))
            {
                if (unit.can_supply())
                {
                    // Supply
                    commands.Add("Supply");
                    IndexRedirect.Add(18);
                }
            }

            if (commands.Count == 0 && unit.cantoing)
            {
                // Wait
                AddWaitCommand(commands);
                // Status
                commands.Add("Status");
                IndexRedirect.Add(15);
            }
            else
            {
                // Status
                commands.Add("Status");
                IndexRedirect.Add(15);
                // Wait
                AddWaitCommand(commands);
            }

            AddSkillCommands(ref commands, unit);

            //@Debug: why?
            Input.clear_locked_repeats();

            return(commands);
        }