public static bool CanAct(ref Husk husk, HuskBrain brain) { if (husk == null) { return(TryResync(ref husk, brain)); } return(true); }
public bool CanUse(Character npc, Husk husk, HuskBrain brain) { if (Criterion != null) { return(Criterion.Judge.Invoke(npc, husk, brain)); } return(true); }
public static bool IsNearStructure(Husk husk, Structure structure) { EntityHitbox hitbox = GetHitbox(husk); if (structure != null) { return(IsNearStructure(hitbox, structure)); } return(false); }
// 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); } } }
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); }
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); }
// 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. }
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); }
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); }
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); }
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); }
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); }
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); }
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()}**."); }
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); }
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); }
// 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. }
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)); }
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); }
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); }
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); }
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"); } }
// 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); }
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."); } }
public static bool CanSeePoint(Husk husk, Vector2 point) { EntityHitbox hitbox = GetHitbox(husk); return(CanSeePoint(hitbox, point)); }
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."); } }
public static Grid <Color> DebugDraw(Sector sector, Husk husk) { return(DrawSector(husk, sector)); }
// 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)); }
internal static IEnumerable <Structure> GetVisibleStructures(Husk husk, Sector sector) => GetVisibleStructures(GetHitbox(husk), sector.Structures);
public static bool CanSeePoint(Husk husk, float x, float y) { EntityHitbox hitbox = GetHitbox(husk); return(CanSeePoint(hitbox, x, y)); }