/// <summary> /// This method determines if the exit is currently passable. This is primarily to detect if /// 1) Hidden exits have been exposed -or- /// 2) Key/Door/Gate exits have been opened /// This will make no attempt to determine if the player has enough money or is the right /// level/class/race/item to enter the exit. Those parameters should have already been verified via /// the pathfinding algorithm. /// </summary> /// <param name="room"></param> /// <returns></returns> public virtual bool IsCurrentlyPassable(MajorModelEntities model, SeenRoom room) { if (room.Exits.Any(x => x.Equals(model.PlainExitNames[(int)Direction], StringComparison.InvariantCultureIgnoreCase))) { return(true); } return(false); }
public override bool IsCurrentlyPassable(MajorModelEntities model, SeenRoom room) { var regex = KeyExitData.GetBarrierExitRegex(model, this, BarrierState.Open); if (room.Exits.Any(x => regex.IsMatch(x))) { return(true); } return(false); }
public static int GetTotalMoney(this IItemContainer container, MajorModelEntities model) { int sum = 0; foreach (var pair in container.Money.Dictionary) { sum += pair.Value * model.Currencies[pair.Key]; } return(sum); }
public override bool IsCurrentlyPassable(MajorModelEntities model, SeenRoom room) { string exitName = ExitName(model); if (room.Exits.Any(x => x.Equals(exitName, StringComparison.InvariantCultureIgnoreCase))) { return(true); } return(false); }
public static Regex GetBarrierExitRegex(MajorModelEntities model, ExitData exit, params BarrierState[] barrierStates) { string objectName = model.DoorNames[(int)exit.Direction]; if (exit.ExitType == ExitType.Gate) { objectName = model.GateNames[(int)exit.Direction]; } string barrierSegment = String.Join("|", barrierStates.Select(x => model.BarrierStateNames[(int)x])); barrierSegment = String.Format("({0}) ", barrierSegment); return(new Regex(barrierSegment + objectName + " " + model.SpecialExitNames[(int)exit.Direction], RegexOptions.IgnoreCase)); }
public override ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings) { var reqs = new ExitUsageRequirements(); if (settings.PartyCharacters.Any(x => x.Class.Number == ClassNotAllowed) || settings.PartyCharacters.Any(x => x.Class.Number != ClassAllowed)) { // Detected a disallowed class. reqs.Method = ExitMethod.CannotPass; return(reqs); } // All party members can pass reqs.Method = ExitMethod.Normal; return(reqs); }
public override ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings) { var reqs = new ExitUsageRequirements(); if (settings.PartyCharacters.Any(x => x.Level < MinimumLevel) || settings.PartyCharacters.Any(x => x.Level > MaximumLevel)) { // Detected a disallowed level. reqs.Method = ExitMethod.CannotPass; return(reqs); } // All party members can pass reqs.Method = ExitMethod.Normal; return(reqs); }
/// <summary> /// Gets the exit name for the hidden exit, if it were to be displayed to the user in the current room. /// </summary> /// <param name="model"></param> /// <returns></returns> public string ExitName(MajorModelEntities model) { var message = model.Messages.SingleOrDefault(x => x.Number == this.ExitDescriptionMessage); string text = null; if (message != null) { text = message.Line_1; } else { text = model.SecretPassageText; } return(text.Replace("%s", model.SpecialExitNames[(int)Direction])); }
public override ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings) { var reqs = new ExitUsageRequirements(); if (settings.PartyCharacters.Any(p => !p.Items.Any(i => i.Number == ItemRequired))) { // At least one member does not have the required item reqs.Method = ExitMethod.NeedItem; reqs.RequiredItemNumber = ItemRequired; return(reqs); } // All party members have the required item, we're good to go. reqs.Method = ExitMethod.Normal; return(reqs); }
public override ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings) { var reqs = new ExitUsageRequirements(); var moneyRequired = model.TollMultiplier * TollAmountRequired; if (settings.PartyCharacters.Any(x => x.GetTotalMoney(model) < moneyRequired)) { // someone doesn't have enough money, or hasn't disclosed that they have the money. // So, mark the exit as needing money. reqs.Method = ExitMethod.NeedMoney; reqs.RequiredMoneyAmount = moneyRequired; return(reqs); } // All party members have the required money, we're good to go. reqs.Method = ExitMethod.Normal; return(reqs); }
public static ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings, int chanceToPickOrBash, int keyRequired) { var reqs = new ExitUsageRequirements(); int chanceOfPicking = settings.PartyCharacters.Max(p => p.Picklocks) + chanceToPickOrBash; int chanceOfBashing = settings.PartyCharacters.Max(p => p.Strength) + chanceToPickOrBash; if (chanceOfPicking > settings.JustPickOrBashThreshold || chanceOfBashing > settings.JustPickOrBashThreshold) { // Good chance of picking or bashing this lock, pick/bash it even if the user has the item to save // the number of uses on it. reqs.Method = ExitMethod.PickOrBash; return(reqs); } if (keyRequired != 0 && settings.PartyCharacters.Any(p => p.Items.Any(x => x.Number == keyRequired))) { // Low or no chance of picking lock, but a party member has the item, so use it. reqs.Method = ExitMethod.UseItem; reqs.RequiredItemNumber = keyRequired; return(reqs); } if (chanceOfPicking > 0 || chanceOfBashing > 0) { // Low but some chance of picking the lock, user does not have the item reqs.Method = ExitMethod.PickOrBash; return(reqs); } if (keyRequired == 0) { // There is no way through this exit; you cannot pick it, and there is no key to obtain. reqs.Method = ExitMethod.CannotPass; return(reqs); } // User cannot pick, user has no item. Note the restriction so you can offer him a way around. reqs.Method = ExitMethod.NeedItem; reqs.RequiredItemNumber = keyRequired; return(reqs); }
public override ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings) { return(DoorExitData.CanUseExit(model, settings, ChanceToPickOrBash, KeyRequired)); }
public static List <OutputCommand> Pathfind(MajorModelEntities model, RoomNumber start, RoomNumber finish, PathfindingSettings settings) { var dictionary = new Dictionary <RoomNumber, RoomInfo>(); var queue = new C5.IntervalHeap <RoomInfo>(new RoomInfoComparer()); var firstRoom = model.GetRoom(start); var firstInfo = new RoomInfo() { Room = firstRoom, Distance = 0 }; queue.Add(ref firstInfo.Handle, firstInfo); dictionary[firstRoom.RoomNumber] = firstInfo; RoomInfo destination = null; while (!queue.IsEmpty) { var info = queue.DeleteMin(); // we found the finish, so exit. if (info.Room.RoomNumber == finish) { destination = info; break; } var exits = from exit in info.Room.GetExits() where exit.ExitType != ExitType.RemoteAction select exit; foreach (var exit in exits) { // query the exit to see if it can be used in our current state. var requirements = exit.CanUseExit(model, settings); if (requirements.Method == ExitMethod.CannotPass) { continue; } var adjacentNumber = exit.AdjacentRoomNumber; RoomInfo adjacent = null; if (!dictionary.TryGetValue(adjacentNumber, out adjacent)) { adjacent = new RoomInfo(); adjacent.Room = model.GetRoom(adjacentNumber); adjacent.Distance = Int32.MaxValue; dictionary[adjacentNumber] = adjacent; } int travelCost = 1; // TODO: set to 1 for now, adjust later as heuristics play out. if (info.Distance + travelCost < adjacent.Distance) { adjacent.Distance = info.Distance + travelCost; adjacent.Previous = info; adjacent.PreviousExit = exit; adjacent.Requirements = requirements; if (adjacent.Handle == null) { queue.Add(ref adjacent.Handle, adjacent); } else { queue.Replace(adjacent.Handle, adjacent); } } } } if (destination != null) { List <OutputCommand> list = new List <OutputCommand>(); var x = destination; while (x.Previous != null) { list.Add(x.PreviousExit.GetOutputCommand(x.Requirements)); x = x.Previous; } list.Reverse(); return(list); } else { return(null); } }
public static void PopulateInventory(this IItemContainer container, MatchCollection itemMatches, MatchCollection keyMatches, MajorModelEntities model) { container.ClearInventory(); if (itemMatches != null) { foreach (Match match in itemMatches) { var name = match.Groups["name"].Value; int quantity = 1; if (match.Groups["quantity"].Success) { quantity = Int32.Parse(match.Groups["quantity"].Value); } if (model.Currencies.ContainsKey(match.Groups["name"].Value)) { container.Money[name] = quantity; } else { var item = model.GetItem(name); for (int i = 0; i < quantity; i++) { container.AddItem(item); } if (match.Groups["equipped"].Success) { int?readied = null; if (match.Groups["readiedlength"].Success) { readied = Int32.Parse(match.Groups["readiedlength"].Value); } container.EquipItem(match.Groups["equipped"].Value, readied, item); } } } } if (keyMatches != null) { foreach (Match match in keyMatches) { var name = match.Groups["name"].Value; int quantity = 1; if (match.Groups["quantity"].Success) { quantity = Int32.Parse(match.Groups["quantity"].Value); } if (quantity > 1) { name = name.Substring(0, name.Length - 1); // chop off the trailing "s" if there's multiple items. } var item = model.GetItem(name); for (int i = 0; i < quantity; i++) { container.AddItem(item); } } } }
public virtual ExitUsageRequirements CanUseExit(MajorModelEntities model, PathfindingSettings settings) { return(new ExitUsageRequirements()); }