示例#1
0
        public static bool CanAct(ref Husk husk, HuskBrain brain)
        {
            if (husk == null)
            {
                return(TryResync(ref husk, brain));
            }

            return(true);
        }
示例#2
0
        public bool CanUse(Character npc, Husk husk, HuskBrain brain)
        {
            if (Criterion != null)
            {
                return(Criterion.Judge.Invoke(npc, husk, brain));
            }

            return(true);
        }
示例#3
0
        public static bool IsNearStructure(Husk husk, Structure structure)
        {
            EntityHitbox hitbox = GetHitbox(husk);

            if (structure != null)
            {
                return(IsNearStructure(hitbox, structure));
            }

            return(false);
        }
示例#4
0
        // gets a collection of available replies for the player to use based
        // on the criteria met.
        // Chat logs store all used dialog IDs already. If CanRepeat is false on the specified ID
        // it can no longer be referenced.
        public IEnumerable <Dialog> GetAvailableReplys(Character character, Husk husk, HuskBrain brain, ChatLog log, Dialog dialog)
        {
            foreach (string replyId in dialog.ReplyIds)
            {
                var reply = GetDialog(replyId);

                if (reply.Criterion?.Judge.Invoke(character, husk, brain) ?? true)
                {
                    yield return(reply);
                }
            }
        }
示例#5
0
        public static bool IsInLocation(Husk husk, LocationType type, out Location location)
        {
            location = null;
            var current = husk.Location.GetLocation();

            if (type.HasFlag(current.Type))
            {
                location = current;
                return(true);
            }

            return(false);
        }
示例#6
0
        public static bool IsNearClosestStructure(Husk husk, out Structure closest)
        {
            EntityHitbox hitbox = GetHitbox(husk);

            closest = GetClosestStructure(husk);

            if (closest != null)
            {
                return(CanSeeStructure(hitbox, closest));
            }

            return(false);
        }
示例#7
0
        // gets the best reply for a dialog based on the criteria met for an NPC.
        // and the current dialog given.
        public Dialog GetBestReply(Character character, Husk husk, HuskBrain brain, ChatLog log, Dialog dialog)
        {
            var bestReplys = GetAvailableReplys(character, husk, brain, log, dialog)
                             .GroupBy(x => x.Criterion?.Priority ?? 0)
                             .OrderByDescending(x => x.Key);

            if (bestReplys?.Count() > 0)
            {
                return(Randomizer.Choose(bestReplys.First()));
            }

            return(null); // there isn't a reply.
        }
示例#8
0
        public static bool CanChatWith(Husk husk, string characterId, out Character character)
        {
            character = null;
            var characters = GetVisibleCharacters(husk);

            if (characters.Any(x => x.Id == characterId))
            {
                character = characters.First(x => x.Id == characterId);
                return(true);
            }

            return(false);
        }
示例#9
0
        public static bool IsInLocation <TLocation>(Husk husk, out TLocation location)
            where TLocation : Location
        {
            location = default;
            var current = husk.Location.GetLocation();

            if (current is TLocation)
            {
                location = current as TLocation;
                return(true);
            }

            return(false);
        }
示例#10
0
        public static void Recover(Husk husk, HuskBrain brain, Memorial memorial)
        {
            if (!brain.Memorials.Contains(memorial))
            {
                return;
            }

            // TODO: create a system that allows you to selectively recover items
            husk.Backpack = memorial.Backpack;
            // MemorialHandler.StartAsync(); // You search through your past items. Most are missing, but you can take what you need.
            // (List out all of the available items, modules, and upgrades here)

            brain.Memorials.Remove(memorial);
        }
示例#11
0
        public static bool TryIdentifyStructure(Husk husk, HuskBrain brain, Structure structure)
        {
            if (structure != null)
            {
                if (brain.HasDiscoveredRegion(structure.Id))
                {
                    return(false);
                }

                brain.IdentifyRegion(structure.Id);
                return(true);
            }

            return(false);
        }
示例#12
0
        public static Husk Initialize(HuskBrain brain)
        {
            var location = World.Find("area0");

            if (location == null)
            {
                throw new ArgumentException("The specified initial location ID does not point to a location.");
            }

            var husk = new Husk(location.GetLocator());

            brain.SetFlag(DesyncFlags.Initialized);

            return(husk);
        }
示例#13
0
        public static bool TryLeaveLocation(Husk husk)
        {
            Location location = husk.Location.GetLocation();

            switch (location.Type)
            {
            case LocationType.Area:
                Area    area     = location as Area;
                Vector2 entrance = area.Entrances?.FirstOrDefault() ?? area.Shape.Position;
                husk.Location.X = entrance.X;
                husk.Location.Y = entrance.Y;

                // this should point back to the sector.
                husk.Location.Id = location.GetParent().Id;
                break;

            case LocationType.Construct:
                var parent = location.GetParent();

                if (parent == null)
                {
                    throw new ArgumentException("The specified location does not have a parent to exit.");
                }

                if (parent?.Type == LocationType.Area)
                {
                    husk.Location.X  = parent.Shape.X;
                    husk.Location.Y  = parent.Shape.Y;
                    husk.Location.Id = parent.Id;
                }
                else
                {
                    // just move their position to the outskirts of the inner location.
                    // TODO: Implement entrance references for locations.
                    husk.Location.X  = location.Shape.X;
                    husk.Location.Y  = location.Shape.Y;
                    husk.Location.Id = parent.Id;
                }
                break;

            default:     // if (!(LocationType.Area | LocationType.Construct).HasFlag(location.Type))
                return(false);
            }

            return(true);
        }
示例#14
0
        public static string WriteVisibleCharacters(Husk husk)
        {
            var npcs = GetVisibleCharacters(husk);

            if (npcs?.Count() > 0)
            {
                var result    = new StringBuilder();
                var summaries = npcs.Select(x => $"> `{x.Id}` • {x.Name}");

                result.AppendLine($"**Available NPCs** ({husk.Location.GetInnerName()}):");
                result.AppendJoin("\n", summaries);

                return(result.ToString());
            }

            return($"There isn't anyone to talk to in **{husk.Location.GetInnerName()}**.");
        }
示例#15
0
        public static bool CanShopAt(Husk husk, out Market market)
        {
            if (IsInLocation(husk, out market))
            {
                if (market.IsActive())
                {
                    return(true);
                }
                else
                {
                    // If the market is closed, attempt to take them out of the market if they are in it
                    TryLeaveLocation(husk);
                }
            }

            return(false);
        }
示例#16
0
        public bool Judge(Husk husk, HuskBrain brain)
        {
            if (brain.HasFlag(UnlockId))
            {
                return(true);
            }

            foreach (string flag in RequiredFlags)
            {
                if (!brain.HasFlag(flag))
                {
                    return(false);
                }
            }

            brain.SetFlag(UnlockId);
            return(true);
        }
示例#17
0
        // TODO: Finish creating method.
        public static List <Route> GetRoutes(Husk husk)
        {
            // ensure that the husk travelling is in a location that supports routes.
            // routes are a path reference from one location to the other.
            // route progression is determined by if the path intersects with a barrier
            // otherwise, Routes can be placed, and could be enforced.
            // TODO: Account for possible barriers in the surrounding area.

            // use user's current position.
            var routes = new List <Route>();

            // if the user is in an AREA, do not account for travel time when listing CONSTRUCTS.
            // if the user is in a SECTOR, account for AREAS


            return(routes);
            // foreach route, you would want to get the travel time based on position.
        }
示例#18
0
        internal static Structure GetClosestStructure(Husk husk)
        {
            EntityHitbox hitbox = GetHitbox(husk);

            // FIELD
            // SECTOR
            // WORLD

            // AREA (all structures are instant)

            if (!IsInLocation(husk, out Sector sector))
            {
                throw new ArgumentException("The specified Husk is not currently within a valid location.");
            }

            // this change now only gets the closest VISIBLE structure
            // GetVisibleStructures(hitbox, sector.Structures)
            return(GetClosestStructure(hitbox, sector.Structures));
        }
示例#19
0
        public static TravelResult TryGoTo(Husk husk, float x, float y, out Destination attempted)
        {
            attempted = null;

            if (!(LocationType.Sector | LocationType.Field | LocationType.World).HasFlag(husk.Location.GetInnerType()))
            {
                throw new ArgumentException("The specified Husk is not within a coordinate-based location.");
            }

            if (husk.Destination != null)
            {
                if (!husk.Destination.Complete)
                {
                    throw new ArgumentException("Husk is currently in transit.");
                }
                else
                {
                    UpdateLocation(husk, husk.Destination);
                }
            }

            Route route = CreateRoute(husk.Location.X, husk.Location.Y, x, y);
            var   now   = DateTime.UtcNow;

            // TODO: Implement region naming
            // sector.GetInnerRegion(float x, float y);
            // iterates through all specified regions, and returns the one that contains those coordinates
            var info = new Destination(husk.Location.WorldId, husk.Location.Id, x, y, now, now.Add(route.Time));

            attempted = info;

            // If the travel time is short enough, just instantly go to the location.
            if (route.GetTime().TotalSeconds <= 1f)
            {
                UpdateLocation(husk, info);
                return(TravelResult.Instant);
            }

            husk.Destination = info;

            return(TravelResult.Start);
        }
示例#20
0
        internal static bool TryResync(ref Husk husk, HuskBrain brain)
        {
            if (husk != null)
            {
                return(false);
            }

            if (!brain.ResyncAt.HasValue)
            {
                return(false);
            }

            if (DateTime.UtcNow - brain.ResyncAt.Value <= TimeSpan.Zero)
            {
                return(false);
            }

            husk           = new Husk(World.Find("ctr0").GetLocator());
            brain.ResyncAt = null;
            return(true);
        }
示例#21
0
        public static bool CanMove(Husk husk, out string notification)
        {
            notification = null;

            if (husk.Destination == null)
            {
                return(true);
            }

            if (!husk.Destination.Complete)
            {
                return(false);
            }

            notification = $"You have arrived at **{husk.Destination.GetInnerName()}**.";

            UpdateLocation(husk, husk.Destination);
            husk.Destination = null;

            return(true);
        }
示例#22
0
        public static TravelResult TryGoTo(Husk husk, HuskBrain brain, string id, out Region attempted)
        {
            attempted = null;

            Location location = husk.Location.GetLocation();

            switch (location.Type)
            {
            case LocationType.Area:
                foreach (Construct construct in (location as Area).Constructs)
                {
                    if (construct.Id == id)
                    {
                        continue;
                    }

                    attempted = construct;

                    if (construct is Market)
                    {
                        if (!(construct as Market).IsActive())
                        {
                            return(TravelResult.Closed);
                        }
                    }

                    husk.Location.Id = construct.Id;
                    return(TravelResult.Instant);
                }

                return(TravelResult.Invalid);

            case LocationType.Sector:
                return(TryGoToInSector(husk, brain, id, out attempted));

            default:
                throw new NotImplementedException("Travelling in this location has not been implemented yet");
            }
        }
示例#23
0
        // This draws all hitboxes in a sector.
        private static Grid <Color> DrawSector(Husk husk, Sector sector)
        {
            var canvas = CreateCanvas(sector.Shape, GammaPalette.GammaGreen[Gamma.Min]);

            DrawHitboxOn(canvas,
                         GetHitbox(husk),
                         GammaPalette.GammaGreen[Gamma.Standard],
                         GammaPalette.GammaGreen[Gamma.StandardDim],
                         GammaPalette.Alconia[Gamma.Min]);

            if (sector.Regions?.Count > 0)
            {
                foreach (Region region in sector.Regions)
                {
                    DrawRectangleOn(canvas, region.Shape, GammaPalette.GammaGreen[Gamma.Dim]);
                }
            }

            foreach (Area area in sector.Areas)
            {
                DrawRectangleOn(canvas, area.Shape, GammaPalette.GammaGreen[Gamma.Bright]);

                if (area.Entrances?.Count > 0)
                {
                    foreach (Vector2 entrance in area.Entrances)
                    {
                        DrawPointOn(canvas, entrance, GammaPalette.GammaGreen[Gamma.Max]);
                    }
                }
            }

            foreach (Structure structure in sector.Structures)
            {
                DrawRectangleOn(canvas, structure.Shape, GammaPalette.NeonRed[Gamma.Max]);
            }

            return(canvas.Pixels);
        }
示例#24
0
        private static IEnumerable <Character> GetVisibleCharacters(Husk husk)
        {
            Location location = husk.Location.GetLocation();

            switch (location.Type)
            {
            case LocationType.Area:
                return(Characters.Values.Where(x => x.DefaultLocation.Id == location.Id));

            case LocationType.Construct:
                var construct  = location as Construct;
                var characters = Characters.Values.Where(x => x.DefaultLocation.Id == location.Id).ToList();

                if (construct.Tag.HasFlag(ConstructType.Market))
                {
                    characters.AddRange((location as Market).Npcs);
                }

                if (construct.Tag.HasFlag(ConstructType.Highrise))
                {
                    characters.AddRange((location as Highrise).Npcs);
                }

                return(Characters.Values.Where(x => x.DefaultLocation.Id == location.Id));

            case LocationType.Sector:
            case LocationType.Field:
            case LocationType.World:
                return(Characters.Values.Where(x =>
                                               x.DefaultLocation.Id == location.Id &&
                                               CanSeePoint(husk, x.DefaultLocation.Vector)));

            default:
                throw new ArgumentException("The specified Husk is currently at a location that does not support NPCs.");
            }
        }
示例#25
0
        public static bool CanSeePoint(Husk husk, Vector2 point)
        {
            EntityHitbox hitbox = GetHitbox(husk);

            return(CanSeePoint(hitbox, point));
        }
示例#26
0
        public static string WriteVisibleLocations(Husk husk, HuskBrain brain)
        {
            Location location  = husk.Location.GetLocation();
            var      locations = new StringBuilder();

            switch (location.Type)
            {
            case LocationType.Area:
                var area = location as Area;
                locations.AppendLine($"**Available Locations** ({area.Name}):");

                if (area.Constructs?.Count > 0)
                {
                    locations.AppendLine($"**Available Locations** ({area.Name}):");
                    locations.AppendJoin("\n", area.Constructs.Select(x => $"> `{x.Id}` • {x.Name}"));
                    return(locations.ToString());
                }

                return("There isn't anything close by. Maybe try going to a different area?");

            case LocationType.Sector:
                var sector     = location as Sector;
                var structures = GetVisibleStructures(husk, sector);

                if (sector.Areas?.Count == 0 && structures?.Count() == 0)
                {
                    return("There isn't anything close by. Try looking around!");
                }

                if (sector.Areas?.Count > 0)
                {
                    locations.AppendLine($"**Available Areas** ({sector.Name}):");
                    locations.AppendJoin("\n", sector.Areas.Select(x => $"> `{x.Id} • {x.Name}`"));
                }

                if (structures?.Count() > 0)
                {
                    locations.AppendLine();
                    locations.AppendLine($"**Points of Interest**:");

                    var summaries = structures.Select(x =>
                                                      brain.HasDiscoveredRegion(x.Id)
                        ? $"> `{x.Id}` • {x.Name}"
                        : $"> `({x.Shape.Position.X}, {x.Shape.Position.Y})` • Unknown Structure");

                    locations.AppendJoin("\n", summaries);
                }

                if (brain.Memorials?.Where(x => x.Location.Id == sector.Id).Count() > 0)
                {
                    locations.Append("\n");
                    var summaries = brain.Memorials.Select(x =>
                                                           $">` ({x.Location.X}, {x.Location.Y})` • Memorial");

                    locations.AppendJoin("\n", summaries);
                }

                return(locations.ToString());

            default:
                throw new Exception("The specified Husk is currently at an invalid location.");
            }
        }
示例#27
0
 public static Grid <Color> DebugDraw(Sector sector, Husk husk)
 {
     return(DrawSector(husk, sector));
 }
示例#28
0
 // gets the list of starting dialogs to choose from based on the npc and player.
 public IEnumerable <Dialog> GetEntryDialogs(Character npc, Husk husk, HuskBrain brain, ChatLog log)
 {
     return(Values.Where(x => x.Type == DialogType.Initial));
 }
示例#29
0
 internal static IEnumerable <Structure> GetVisibleStructures(Husk husk, Sector sector)
 => GetVisibleStructures(GetHitbox(husk), sector.Structures);
示例#30
0
        public static bool CanSeePoint(Husk husk, float x, float y)
        {
            EntityHitbox hitbox = GetHitbox(husk);

            return(CanSeePoint(hitbox, x, y));
        }