private bool TempRemove(Character character, Stack <Token> list, string slot) { foreach (var carriedItem in character.GetToken("items").Tokens) { if (!carriedItem.HasToken("equipped")) { continue; } var find = NoxicoGame.KnownItems.Find(x => x.ID == carriedItem.Name); var equip = find.GetToken("equipable"); if (equip == null) { System.Windows.Forms.MessageBox.Show("Item " + carriedItem.Name + " is marked as equipped, but " + find.Name + " is not equippable."); carriedItem.RemoveToken("equipped"); continue; } if (equip.HasToken(slot)) { if (equip.HasToken("reach")) { return(true); } var success = find.Unequip(character); if (success) { list.Push(carriedItem); } return(success); } } return(true); }
public void UpdateCandle() { var game = NoxicoGame.Me; var homeBoard = game.GetBoard((int)Character.GetToken("homeboard").Value); var candle = (Clutter)homeBoard.Entities.First(e => e is Clutter && e.ID == "lifeCandle"); if (Character.HasToken("easymode")) { candle.Description = i18n.GetString("candle_easymode"); } else if (Lives == 0) { candle.Description = i18n.GetString("candle_0"); } else if (Lives == 1) { candle.Description = i18n.GetString("candle_1"); } else if (Lives < 4) { candle.Description = i18n.GetString("candle_3"); } else if (Lives < 7) { candle.Description = i18n.GetString("candle_6"); } else { candle.Description = i18n.GetString("candle_X"); } }
public void CheckHands(Character character, string slot) { var max = slot == "ring" ? 8 : 2; if (character.HasToken("monoceros")) { max = slot == "ring" ? 10 : 3; } if (character.HasToken("quadruped")) { if (slot == "hand") { max = character.HasToken("monoceros") ? 2 : 1; } else { max = character.HasToken("monoceros") ? 2 : 0; } } /* therefore: * normal pony unicorn humancorn * rings 8 0 2 10 * weapons 2 1 2 3 */ var worn = 0; var items = character.GetToken("items"); foreach (var carriedItem in items.Tokens) { if (!carriedItem.HasToken("equipped")) { continue; } var find = NoxicoGame.KnownItems.Find(x => x.ID == carriedItem.Name); if (find == null) { continue; } var equip = find.GetToken("equipable"); if (equip.HasToken(slot)) { worn++; } } if (worn >= max) { var error = "yourhandsarefull"; if (max == 1 && slot == "hand") { error = "yourmouthisfull"; } else if (max == 2 && slot == "ring") { error = "yourhornisfull"; } throw new ItemException(i18n.GetString(error)); } }
public void Take(Character taker, Board ParentBoard) { if (!taker.HasToken("items")) { taker.Tokens.Add(new Token("items")); } taker.GetToken("items").Tokens.Add(Token); taker.CheckHasteSlow(); ParentBoard.EntitiesToRemove.Add(this); }
/// <summary> /// Provides a description of a character's hand based on their body type. /// </summary> /// <param name="character">The character to be evaluated.</param> /// <param name="plural">If set to true, the returned description will be for both hands.</param> /// <returns>A string containing a description of the hand type.</returns> public static string Hand(Character character, bool plural = false) { if (character.HasToken("quadruped")) { return(Foot(character.GetToken("legs"), plural)); } //Clawed hands and such can go here. var request = descTable.Path("hand/default"); return(request.Text.Pluralize(plural ? 2 : 1)); }
public void Consume(Character carrier, Token carriedItem) { if (this.HasToken("charge")) { var charge = carriedItem.Path("charge"); if (charge == null && carriedItem.Name == "charge") { charge = carriedItem; } if (charge == null || charge.Value == 1) { if (HasToken("revert")) { carriedItem.Name = GetToken("revert").Text; carriedItem.Tokens.Clear(); } else { carrier.GetToken("items").Tokens.Remove(carriedItem); carrier.CheckHasteSlow(); } } else { charge.Value--; } } else { if (HasToken("revert")) { carriedItem.Name = GetToken("revert").Text; carriedItem.Tokens.Clear(); } else { carrier.GetToken("items").Tokens.Remove(carriedItem); carrier.CheckHasteSlow(); } } }
/// <summary> /// Sets up a ContainerMan subscreen for trading with a vendor. /// </summary> /// <param name="vendor">The Character whose items to display on the left.</param> public static void Setup(Character vendor) { NoxicoGame.Mode = UserMode.Subscreen; NoxicoGame.Subscreen = ContainerMan.Handler; Subscreens.FirstDraw = true; other = vendor.GetToken("items"); title = vendor.Name.ToString(true); mode = ContainerMode.Vendor; vendorChar = vendor; vendorCaughtYou = false; }
public void Respawn() { var game = NoxicoGame.Me; var homeBoard = game.GetBoard((int)Character.GetToken("homeboard").Value); homeBoard.Update(); var bed = homeBoard.Entities.First(e => e is Clutter && e.ID == "Bed_playerRespawn"); if (ParentBoard != homeBoard) { OpenBoard(homeBoard.BoardNum); } XPosition = bed.XPosition; YPosition = bed.YPosition; #if DEBUG if (!Character.HasToken("easymode") && !Character.HasToken("wizard")) #else if (!Character.HasToken("easymode")) #endif { Lives--; } Character.Health = Character.MaximumHealth * 0.75f; UpdateCandle(); }
public void EndTurn() { var nrg = Energy; Energy = 5000; var r = Lua.Environment.EachBoardCharTurn(this, this.Character); Energy = nrg; NoxicoGame.PlayerReady = false; if (Character.HasToken("flying")) { var f = Character.GetToken("flying"); f.Value--; if (!Character.HasToken("wings") || Character.GetToken("wings").HasToken("small")) { NoxicoGame.AddMessage(i18n.GetString("losewings")); f.Value = -10; } if (f.Value <= 0) { LandFromFlight(true); } } if (ParentBoard == null) { return; } ParentBoard.Update(true); if (ParentBoard.IsBurning(YPosition, XPosition)) { Hurt(10, "death_burned", null, false, false); } //Leave EntitiesToAdd/Remove to Board.Update next passive cycle. }
public override bool Hurt(float damage, string cause, object aggressor, bool finishable = false, bool leaveCorpse = true) { if (AutoTravelling) { NoxicoGame.AddMessage(i18n.Format("autotravelstop")); AutoTravelling = false; } if (Character.HasItemEquipped("eternitybrooch")) { var brooch = Character.GetEquippedItemBySlot("neck"); //can assume the neck slot has the brooch. var today = NoxicoGame.InGameTime.DayOfYear; if (!brooch.HasToken("lastTrigger")) { brooch.AddToken("lastTrigger", today - 2); } if (Math.Abs(brooch.GetToken("lastTrigger").Value - today) >= 2 && Character.Health - damage <= 0) { brooch.GetToken("lastTrigger").Value = today; NoxicoGame.AddMessage(i18n.GetString("eternitybrooched")); Character.Health = Character.MaximumHealth; Reposition(); return(false); } } var dead = base.Hurt(damage, cause, aggressor, finishable); if (dead) { if (aggressor != null && aggressor is BoardChar) { var aggChar = ((BoardChar)aggressor).Character; var relation = Character.Path("ships/" + aggChar.ID); if (relation == null) { relation = new Token(aggChar.ID); Character.Path("ships").Tokens.Add(relation); } relation.AddToken("killer"); if (aggChar.HasToken("stolenfrom")) { var myItems = Character.GetToken("items").Tokens; var hisItems = aggChar.GetToken("items").Tokens; var stolenGoods = myItems.Where(t => t.HasToken("owner") && t.GetToken("owner").Text == aggChar.ID).ToList(); foreach (var item in stolenGoods) { hisItems.Add(item); myItems.Remove(item); } aggChar.GetToken("stolenfrom").Name = "wasstolenfrom"; aggChar.RemoveToken("hostile"); } } if (Lives == 0) { Character.AddToken("gameover"); NoxicoGame.AddMessage(i18n.GetString("gameover_title"), Color.Red); //var playerFile = Path.Combine(NoxicoGame.SavePath, NoxicoGame.WorldName, "player.bin"); //File.Delete(playerFile); var world = string.Empty; if (NoxicoGame.WorldName != "<Testing Arena>") { world = System.IO.Path.Combine(NoxicoGame.SavePath, NoxicoGame.WorldName); } NoxicoGame.Sound.PlayMusic("set://Death"); NoxicoGame.InGame = false; var c = i18n.GetString(cause + "_player"); if (c[0] == '[') { c = i18n.GetString(cause); } MessageBox.Ask( i18n.Format("youdied", c), () => { Character.CreateInfoDump(); if (NoxicoGame.WorldName != "<Testing Arena>") { Directory.Delete(world, true); } NoxicoGame.HostForm.Close(); }, () => { if (NoxicoGame.WorldName != "<Testing Arena>") { Directory.Delete(world, true); } NoxicoGame.HostForm.Close(); } ); } else { Respawn(); } } return(dead); }
public override void Update() { //base.Update(); if (NoxicoGame.Mode != UserMode.Walkabout) { return; } //START if (NoxicoGame.IsKeyDown(KeyBinding.Pause) || Vista.Triggers == XInputButtons.Start) { NoxicoGame.ClearKeys(); Pause.Open(); return; } var increase = 200 + (int)Character.GetStat("speed"); if (Character.HasToken("haste")) { increase *= 2; } else if (Character.HasToken("slow")) { increase /= 2; } Energy += increase; if (Energy < 5000) { var wasNight = Toolkit.IsNight(); NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddMilliseconds(increase); if (wasNight && !Toolkit.IsNight()) { ParentBoard.UpdateLightmap(this, true); ParentBoard.Redraw(); } EndTurn(); return; } else { if (!NoxicoGame.PlayerReady) { NoxicoGame.AgeMessages(); } NoxicoGame.PlayerReady = true; Energy = 5000; } CheckForTimedItems(); CheckForCopiers(); if (Character.UpdateSex()) { return; } var sleeping = Character.Path("sleeping"); if (sleeping != null) { Character.Heal(2); sleeping.Value--; if (sleeping.Value <= 0) { Character.RemoveToken("sleeping"); Character.RemoveToken("helpless"); NoxicoGame.AddMessage(i18n.GetString("yougetup")); } NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddMinutes(5); EndTurn(); return; //07-04-13 no more sleepwalking } var helpless = Character.HasToken("helpless"); if (helpless) { if (Random.NextDouble() < 0.05) { Character.Heal(2); NoxicoGame.AddMessage(i18n.GetString("yougetup")); Character.RemoveToken("helpless"); helpless = false; } } var flying = Character.HasToken("flying"); #if DEBUG if (NoxicoGame.KeyMap[Keys.Z]) { NoxicoGame.ClearKeys(); NoxicoGame.InGameTime = NoxicoGame.InGameTime.AddMinutes(30); } #endif //Pause menu moved up so you can pause while <5000. //RIGHT if ((NoxicoGame.IsKeyDown(KeyBinding.Travel) || Vista.Triggers == XInputButtons.RightShoulder)) { NoxicoGame.ClearKeys(); if (!this.ParentBoard.AllowTravel) { if (this.ParentBoard.BoardType == BoardType.Dungeon) { NoxicoGame.AddMessage(i18n.GetString("travel_notfromdungeon")); } else { NoxicoGame.AddMessage(i18n.GetString("travel_notfromwilds")); } return; } Travel.Open(); return; } //LEFT if (NoxicoGame.IsKeyDown(KeyBinding.Rest) || Vista.Triggers == XInputButtons.LeftShoulder) { NoxicoGame.ClearKeys(); Energy -= 1000; EndTurn(); return; } //GREEN if (NoxicoGame.IsKeyDown(KeyBinding.Interact) || Vista.Triggers == XInputButtons.A) { NoxicoGame.ClearKeys(); //NoxicoGame.Messages.Add("[Aim message]"); NoxicoGame.Mode = UserMode.Aiming; NoxicoGame.Cursor.ParentBoard = this.ParentBoard; NoxicoGame.Cursor.XPosition = this.XPosition; NoxicoGame.Cursor.YPosition = this.YPosition; NoxicoGame.Cursor.PopulateTabstops(); NoxicoGame.Cursor.Point(); if (Character.HasToken("tutorial") && !Character.GetToken("tutorial").HasToken("interactmode")) { Character.GetToken("tutorial").AddToken("dointeractmode"); NoxicoGame.CheckForTutorialStuff(); } return; } //BLUE if (NoxicoGame.IsKeyDown(KeyBinding.Items) || Vista.Triggers == XInputButtons.X) { NoxicoGame.ClearKeys(); NoxicoGame.Mode = UserMode.Subscreen; NoxicoGame.Subscreen = Inventory.Handler; Subscreens.FirstDraw = true; return; } //YELLOW if ((NoxicoGame.IsKeyDown(KeyBinding.Fly) || Vista.Triggers == XInputButtons.Y) && !helpless) { NoxicoGame.ClearKeys(); if (Character.HasToken("flying")) { LandFromFlight(); } else { if (Character.HasToken("wings")) { if (Character.GetToken("wings").HasToken("small")) { NoxicoGame.AddMessage(i18n.GetString("wingsaretoosmall")); return; } var tile = ParentBoard.Tilemap[XPosition, YPosition]; if (tile.Definition.Ceiling) { if (Character.GetStat("mind") < 10 || (Character.GetStat("mind") < 20 && Random.NextDouble() < 0.5)) { Hurt(2, "death_crackedagainstceiling", null, false); NoxicoGame.AddMessage(i18n.GetString("hittheceiling")); } else { NoxicoGame.AddMessage(i18n.GetString("cantflyinside")); } return; } //Take off Character.AddToken("flying").Value = 100; NoxicoGame.AddMessage(i18n.GetString("youfly")); return; } NoxicoGame.AddMessage(i18n.GetString("flyneedswings")); } return; } //RED if ((NoxicoGame.IsKeyDown(KeyBinding.Activate) || Vista.Triggers == XInputButtons.B) && !helpless && !flying) { NoxicoGame.ClearKeys(); if (OnWarp()) { CheckWarps(); } var container = ParentBoard.Entities.OfType <Container>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition); if (container != null) { NoxicoGame.ClearKeys(); ContainerMan.Setup(container); return; } //Find dropped items var itemsHere = DroppedItem.GetItemsAt(ParentBoard, XPosition, YPosition); if (itemsHere.Count == 1) { var drop = itemsHere[0]; if (drop != null) { drop.Take(this.Character, ParentBoard); NoxicoGame.Me.Player.Energy -= 1000; NoxicoGame.AddMessage(i18n.Format("youpickup_x", drop.Item.ToString(drop.Token, true))); NoxicoGame.Sound.PlaySound("set://GetItem"); ParentBoard.Redraw(); return; } } else if (itemsHere.Count > 1) { DroppedItem.PickItemsFrom(itemsHere); return; } //Find bed //var bed = ParentBoard.Entities.OfType<Clutter>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition && c.Glyph == 0x147); var bed = ParentBoard.Entities.OfType <Clutter>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition && c.DBRole == "bed"); if (bed != null) { var prompt = "It's " + NoxicoGame.InGameTime.ToShortTimeString() + ", " + NoxicoGame.InGameTime.ToLongDateString() + ". Sleep for how long?"; var options = new Dictionary <object, string>(); foreach (var interval in new[] { 1, 2, 4, 8, 12 }) { options[interval] = Toolkit.Count(interval).Titlecase() + (interval == 1 ? " hour" : " hours"); } options[-1] = "Cancel"; MessageBox.List(prompt, options, () => { if ((int)MessageBox.Answer != -1) { Character.AddToken("helpless"); Character.AddToken("sleeping").Value = (int)MessageBox.Answer * 12; } }, true, true, i18n.GetString("Bed")); } return; } #if DEBUG if (NoxicoGame.KeyMap[Keys.F3]) { NoxicoGame.ClearKeys(); ParentBoard.DumpToHtml(string.Empty); NoxicoGame.AddMessage("Board dumped."); return; } #endif if (helpless) { EndTurn(); return; } if (!AutoTravelling) { if (NoxicoGame.IsKeyDown(KeyBinding.Left) || Vista.DPad == XInputButtons.Left) { this.Move(Direction.West); } else if (NoxicoGame.IsKeyDown(KeyBinding.Right) || Vista.DPad == XInputButtons.Right) { this.Move(Direction.East); } else if (NoxicoGame.IsKeyDown(KeyBinding.Up) || Vista.DPad == XInputButtons.Up) { this.Move(Direction.North); } else if (NoxicoGame.IsKeyDown(KeyBinding.Down) || Vista.DPad == XInputButtons.Down) { this.Move(Direction.South); } //And now, attempting to fire a long range weapon in a cardinal. else if (NoxicoGame.IsKeyDown(KeyBinding.ShootLeft)) { this.QuickFire(Direction.West); } else if (NoxicoGame.IsKeyDown(KeyBinding.ShootRight)) { this.QuickFire(Direction.East); } else if (NoxicoGame.IsKeyDown(KeyBinding.ShootUp)) { this.QuickFire(Direction.North); } else if (NoxicoGame.IsKeyDown(KeyBinding.ShootDown)) { this.QuickFire(Direction.South); } } else { if (NoxicoGame.IsKeyDown(KeyBinding.Left) || NoxicoGame.IsKeyDown(KeyBinding.Right) || NoxicoGame.IsKeyDown(KeyBinding.Up) || NoxicoGame.IsKeyDown(KeyBinding.Down)) //(NoxicoGame.KeyMap[(int)Keys.Left] || NoxicoGame.KeyMap[(int)Keys.Right] || NoxicoGame.KeyMap[(int)Keys.Up] || NoxicoGame.KeyMap[(int)Keys.Down]) { AutoTravelling = false; return; } var x = XPosition; var y = YPosition; var dir = Direction.North; if (AutoTravelMap.RollDown(y, x, ref dir)) { Move(dir); } else { AutoTravelling = false; if ((int)AutoTravelLeave > -1) { this.Move(AutoTravelLeave); } } } }
public override void Move(Direction targetDirection, SolidityCheck check = SolidityCheck.Walker) { var lx = XPosition; var ly = YPosition; check = SolidityCheck.Walker; if (Character.IsSlime) { check = SolidityCheck.DryWalker; } if (Character.HasToken("flying")) { check = SolidityCheck.Flyer; } #region Inter-board travel var n = NoxicoGame.Me; Board otherBoard = null; if (ly == 0 && targetDirection == Direction.North && this.ParentBoard.ToNorth > -1) { otherBoard = n.GetBoard(this.ParentBoard.ToNorth); if (this.CanMove(otherBoard, lx, otherBoard.Height - 1, check) != null) { return; } this.YPosition = otherBoard.Height; OpenBoard(this.ParentBoard.ToNorth); } else if (ly == ParentBoard.Height - 1 && targetDirection == Direction.South && this.ParentBoard.ToSouth > -1) { otherBoard = n.GetBoard(this.ParentBoard.ToSouth); if (this.CanMove(otherBoard, lx, 0, check) != null) { return; } this.YPosition = -1; OpenBoard(this.ParentBoard.ToSouth); } else if (lx == 0 && targetDirection == Direction.West && this.ParentBoard.ToWest > -1) { otherBoard = n.GetBoard(this.ParentBoard.ToWest); if (this.CanMove(otherBoard, otherBoard.Width - 1, ly, check) != null) { return; } this.XPosition = otherBoard.Width; OpenBoard(this.ParentBoard.ToWest); } else if (lx == ParentBoard.Width - 1 && targetDirection == Direction.East && this.ParentBoard.ToEast > -1) { otherBoard = n.GetBoard(this.ParentBoard.ToEast); if (this.CanMove(otherBoard, 0, ly, check) != null) { return; } this.XPosition = -1; OpenBoard(this.ParentBoard.ToEast); } #endregion if (Character.HasToken("tutorial")) { Character.GetToken("tutorial").Value++; } var newX = this.XPosition; var newY = this.YPosition; Toolkit.PredictLocation(newX, newY, targetDirection, ref newX, ref newY); foreach (var entity in ParentBoard.Entities.Where(x => x.XPosition == newX && x.YPosition == newY)) { if (entity.Blocking) { NoxicoGame.ClearKeys(); if (entity is BoardChar) { var bc = (BoardChar)entity; if (bc.Character.HasToken("hostile") || (bc.Character.HasToken("teambehavior") && bc.Character.DecideTeamBehavior(Character, TeamBehaviorClass.Attacking) != TeamBehaviorAction.Nothing)) { //Strike at your foes! AutoTravelling = false; MeleeAttack(bc); EndTurn(); return; } if (!bc.OnPlayerBump.IsBlank()) { bc.RunScript(bc.OnPlayerBump); return; } //Displace! NoxicoGame.AddMessage(i18n.Format("youdisplacex", bc.Character.GetKnownName(false, false, true)), bc.GetEffectiveColor()); bc.XPosition = this.XPosition; bc.YPosition = this.YPosition; } } } base.Move(targetDirection, check); ParentBoard.AimCamera(XPosition, YPosition); EndTurn(); if (Character.HasToken("squishy") || (Character.Path("skin/type") != null && Character.Path("skin/type").Text == "slime")) { NoxicoGame.Sound.PlaySound("set://Squish"); } else { NoxicoGame.Sound.PlaySound("set://Step"); } if (lx != XPosition || ly != YPosition) { ParentBoard.UpdateLightmap(this, true); this.DijkstraMap.Hotspots[0] = new Point(XPosition, YPosition); this.DijkstraMap.Update(); } else if (AutoTravelling) { AutoTravelling = false; #if DEBUG NoxicoGame.AddMessage("* TEST: couldn't go any further. *"); #endif } NoxicoGame.ContextMessage = null; if (OnWarp()) { NoxicoGame.ContextMessage = i18n.GetString("context_warp"); } else if (ParentBoard.Entities.OfType <DroppedItem>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition) != null) { NoxicoGame.ContextMessage = i18n.GetString("context_droppeditem"); } else if (ParentBoard.Entities.OfType <Container>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition) != null) { if (ParentBoard.Entities.OfType <Container>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition).Token.HasToken("corpse")) { NoxicoGame.ContextMessage = i18n.GetString("context_corpse"); } else { NoxicoGame.ContextMessage = i18n.GetString("context_container"); } } //else if (ParentBoard.Entities.OfType<Clutter>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition && c.Glyph == 0x147) != null) else if (ParentBoard.Entities.OfType <Clutter>().FirstOrDefault(c => c.XPosition == XPosition && c.YPosition == YPosition && c.DBRole == "bed") != null) { NoxicoGame.ContextMessage = i18n.GetString("context_bed"); } if (NoxicoGame.ContextMessage != null) { NoxicoGame.ContextMessage = Toolkit.TranslateKey(KeyBinding.Activate, false, false) + " - " + NoxicoGame.ContextMessage; } }
public bool Unequip(Character character) { /* * if item's slots have covering slots * check for target slot's reachability. * if unreachable, try to temp-remove items in covering slots, recursively. * if still unreachable, error out. * if item is cursed, error out * mark item as unequipped. */ var item = this.CarriedToken.ContainsKey(character.ID) ? this.CarriedToken[character.ID] : null; if (item != null && item.HasToken("cursed") && item.GetToken("cursed").HasToken("known")) { throw new ItemException(item.GetToken("cursed").Text.IsBlank(i18n.Format("cannot_remove_sticky", this.ToString(item, true)), item.GetToken("cursed").Text)); } var equip = this.GetToken("equipable"); var tempRemove = new Stack <Token>(); var items = character.GetToken("items"); foreach (var t in equip.Tokens) { if (t.Name == "underpants") { TempRemove(character, tempRemove, "pants"); } else if (t.Name == "undershirt") { TempRemove(character, tempRemove, "shirt"); } else if (t.Name == "shirt") { TempRemove(character, tempRemove, "jacket"); } else if (t.Name == "jacket") { TempRemove(character, tempRemove, "cloak"); } else if (t.Name == "socks") { TempRemove(character, tempRemove, "shoes"); } } if (item == null) { item = items.Tokens.Find(x => x.Name == this.ID); } if (item.HasToken("cursed")) { item.GetToken("cursed").Tokens.Add(new Token("known")); throw new ItemException(i18n.Format("surprise_its_sticky", this.ToString(item, true))); } var succeed = true; if (!this.OnUnequip.IsBlank()) { succeed = Convert.ToBoolean(RunScript(item, this.OnUnequip, character, null, null)); } if (succeed) { item.RemoveToken("equipped"); } if (!this.OnTimer.IsBlank() && this.Path("timer/evenunequipped") == null) { item.RemoveToken("timer"); } //Not sure about automatically putting pants back on after taking them off to take off underpants... //while (tempRemove.Count > 0) // tempRemove.Pop().Tokens.Add(new Token("equipped")); character.RecalculateStatBonuses(); character.CheckHasteSlow(); return(succeed); }
/// <summary> /// Generic Subscreen handler. /// </summary> public static void Handler() { var keys = NoxicoGame.KeyMap; var player = NoxicoGame.Me.Player; var width = (Program.Cols / 2) - 2; if (Subscreens.FirstDraw) { UIManager.Initialize(); UIManager.Elements.Clear(); //Prepare the left item list and its UIElements... var height = 1; containerTokens.Clear(); containerItems.Clear(); containerList = null; var containerTexts = new List <string>(); containerWindow = new UIWindow(title) { Left = 1, Top = 1, Width = width, Height = 2 + height }; containerList = new UIList(string.Empty, null, containerTexts) { Width = width - 2, Height = height, Index = indexLeft, Background = UIColors.WindowBackground }; containerList.Move(1, 1, containerWindow); UIManager.Elements.Add(containerWindow); var emptyMessage = mode == ContainerMode.Vendor ? i18n.Format("inventory_x_hasnothing", vendorChar.Name.ToString()) : mode == ContainerMode.Corpse ? i18n.GetString("inventory_nothingleft") : i18n.GetString("inventory_empty"); var emptyMessageC = new UILabel(emptyMessage) { Width = width - 3, Height = 1 }; emptyMessageC.Move(2, 1, containerWindow); UIManager.Elements.Add(emptyMessageC); UIManager.Elements.Add(containerList); if (other.Tokens.Count == 0) { containerList.Hidden = true; containerWindow.Height = 3; } else { //Populate the left list... foreach (var carriedItem in other.Tokens) { //Only let vendors sell things meant for sale, not their literal shirt off their back if (vendorChar != null && !carriedItem.HasToken("for_sale")) { continue; } var find = NoxicoGame.KnownItems.Find(x => x.ID == carriedItem.Name); if (find == null) { continue; } containerTokens.Add(carriedItem); containerItems.Add(find); var item = find; var itemString = item.ToString(carriedItem, false, false); if (itemString.Length > width - 5) { itemString = itemString.Disemvowel(); } itemString = itemString.PadEffective(width - 5); //Add any extra sigils. if (mode == ContainerMode.Vendor && carriedItem.HasToken("equipped")) { itemString = itemString.Remove(width - 6) + i18n.GetString("sigil_short_worn"); } if (carriedItem.Path("cursed/known") != null) { itemString = itemString.Remove(width - 6) + "C"; //DO NOT TRANSLATE -- Curses will be replaced with better terms and variants such as "Slippery" or "Sticky". } containerTexts.Add(itemString); } height = containerItems.Count; if (height > Program.Rows - 15) { height = Program.Rows - 15; } if (indexLeft >= containerItems.Count) { indexLeft = containerItems.Count - 1; } containerList.Items.Clear(); containerList.Items.AddRange(containerTexts); containerWindow.Height = 2 + height; containerList.Height = height; } //Prepare the right item list and its UIElements... playerTokens.Clear(); playerItems.Clear(); playerList = null; var playerTexts = new List <string>(); playerWindow = new UIWindow(i18n.GetString("inventory_yours")) { Width = width, Height = 3 }; playerWindow.MoveBeside(2, 0, containerWindow); playerList = new UIList(string.Empty, null, playerTexts) { Width = width - 2, Height = 1, Index = indexRight, Background = UIColors.WindowBackground }; playerList.Move(1, 1, playerWindow); UIManager.Elements.Add(playerWindow); var playerNothing = new UILabel(i18n.GetString("inventory_youhavenothing")) { Left = width + 5, Top = 2, Width = width - 3, Height = 1 }; playerNothing.Move(2, 1, playerWindow); UIManager.Elements.Add(playerNothing); UIManager.Elements.Add(playerList); if (player.Character.GetToken("items").Tokens.Count == 0) { playerList.Hidden = true; playerWindow.Height = 3; } else { //Populate the right list... foreach (var carriedItem in player.Character.GetToken("items").Tokens) { var find = NoxicoGame.KnownItems.Find(x => x.ID == carriedItem.Name); if (find == null) { continue; } playerTokens.Add(carriedItem); playerItems.Add(find); var item = find; var itemString = item.ToString(carriedItem, false, false); if (itemString.Length > width - 5) { itemString = itemString.Disemvowel(); } itemString = itemString.PadEffective(width - 5); if (carriedItem.HasToken("equipped")) { itemString = itemString.Remove(width - 6) + i18n.GetString("sigil_short_worn"); } if (carriedItem.Path("cursed/known") != null) { itemString = itemString.Remove(width - 6) + "C"; //DO NOT TRANSLATE -- Curses will be replaced with better terms and variants such as "Slippery" or "Sticky". } playerTexts.Add(itemString); } var height2 = playerItems.Count; if (height2 == 0) { height2 = 1; } if (height2 > Program.Rows - 15) { height2 = Program.Rows - 15; } if (indexRight >= playerItems.Count) { indexRight = playerItems.Count - 1; } if (height2 > height) { height = height2; } playerList.Items.Clear(); playerList.Items.AddRange(playerTexts); playerWindow.Height = 2 + height2; playerList.Height = height2; } //Build the bottom window. UIManager.Elements.Add(new UILabel(new string(' ', Program.Cols)) { Left = 0, Top = 0, Width = Program.Cols - 1, Height = 1, Background = UIColors.StatusBackground, Foreground = UIColors.StatusForeground }); UIManager.Elements.Add(new UILabel(i18n.GetString(mode == ContainerMode.Vendor ? "inventory_pressenter_vendor" : "inventory_pressenter_container")) { Left = 0, Top = 0, Width = Program.Cols - 1, Height = 1, Background = UIColors.StatusBackground, Foreground = UIColors.StatusForeground }); descriptionWindow = new UIWindow(string.Empty) { Left = 2, Top = Program.Rows - 10, Width = Program.Cols - 4, Height = 8, Title = UIColors.RegularText }; description = new UILabel(string.Empty) { Width = Program.Cols - 8, Height = 5 }; description.Move(2, 1, descriptionWindow); capacity = new UILabel(string.Format("{0:F2}/{1:F2}", player.Character.Carried, player.Character.Capacity)); capacity.MoveBelow(4, -1, descriptionWindow); UIManager.Elements.Add(descriptionWindow); UIManager.Elements.Add(description); UIManager.Elements.Add(capacity); //Should we be trading, replace the weight with a money indication. if (mode == ContainerMode.Vendor) { capacity.Text = i18n.Format("inventory_money", vendorChar.Name.ToString(), vendorChar.GetToken("money").Value, player.Character.GetToken("money").Value); } //FIXME: why is this check a thing? if (containerList != null) { containerList.Change = (s, e) => { if (containerList.Items.Count == 0) { return; } indexLeft = containerList.Index; //Build up the content for the description window. var t = containerTokens[containerList.Index]; var i = containerItems[containerList.Index]; descriptionWindow.Text = i.ToString(t, false, false); var desc = i.GetDescription(t); price = 0; //Reset price no matter the mode so we don't accidentally pay for free shit. if (mode == ContainerMode.Vendor && i.HasToken("price")) { price = i.GetToken("price").Value; desc += "\n" + i18n.Format("inventory_itcosts", price); } if (mode == ContainerMode.Vendor && i.HasToken("equipable") && t.HasToken("equipped")) { desc += "\n" + i18n.Format("inventory_vendorusesthis", vendorChar.Name.ToString()); } description.Text = Toolkit.Wordwrap(desc.SmartQuote(), description.Width); descriptionWindow.Draw(); description.Draw(); capacity.Draw(); }; containerList.Enter = (s, e) => { if (containerList.Items.Count == 0) { return; } //onLeft = true; var tryAttempt = TryRetrieve(player, containerTokens[containerList.Index], containerItems[containerList.Index]); if (tryAttempt.IsBlank()) { //No errors were returned by TryRetrieve, so let's do this. playerItems.Add(containerItems[containerList.Index]); playerTokens.Add(containerTokens[containerList.Index]); playerList.Items.Add(containerList.Items[containerList.Index]); containerItems.RemoveAt(containerList.Index); containerTokens.RemoveAt(containerList.Index); containerList.Items.RemoveAt(containerList.Index); //If this was the bottom-most item, adjust our selection. if (containerList.Index >= containerList.Items.Count) { containerList.Index--; } //If this was the last item, hide the list entirely and switch to the player's side. //We know that's possible -- after all, there must be at -least- one item in there now. if (containerList.Items.Count == 0) { containerList.Hidden = true; keys[NoxicoGame.KeyBindings[KeyBinding.Right]] = true; } else { containerList.Height = (containerList.Items.Count < 10) ? containerList.Items.Count : 10; } playerList.Hidden = false; //always the case. playerList.Height = (playerList.Items.Count < 10) ? playerList.Items.Count : 10; containerWindow.Height = containerList.Height + 2; playerWindow.Height = playerList.Height + 2; capacity.Text = player.Character.Carried + "/" + player.Character.Capacity; if (mode == ContainerMode.Vendor) { capacity.Text = i18n.Format("inventory_money", vendorChar.Name.ToString(), vendorChar.GetToken("money").Value, player.Character.GetToken("money").Value); } containerList.Change(s, e); NoxicoGame.DrawStatus(); UIManager.Draw(); } else { //There was some error returned by TryRetrieve, which we'll show now. MessageBox.Notice(tryAttempt); } }; } //FIXME: same with this check. if (playerList != null) { //We do basically the same thing as above in reverse. playerList.Change = (s, e) => { if (playerList.Items.Count == 0) { return; } indexRight = playerList.Index; var t = playerTokens[playerList.Index]; var i = playerItems[playerList.Index]; descriptionWindow.Text = i.ToString(t, false, false); var desc = i.GetDescription(t); price = 0; if (mode == ContainerMode.Vendor && i.HasToken("price")) { price = i.GetToken("price").Value; desc += "\n" + i18n.Format("inventory_itcosts", price); } //This is one of the few differences. if (t.Path("cursed/path") != null) { desc += "\nThis item is cursed and can't be removed."; //DO NOT TRANSLATE -- Curses will be replaced with better terms and variants such as "Slippery" or "Sticky". } else if (i.HasToken("equipable") && t.HasToken("equipped")) { desc += "\n" + i18n.GetString("inventory_youusethis"); } description.Text = Toolkit.Wordwrap(desc.SmartQuote(), description.Width); descriptionWindow.Draw(); description.Draw(); capacity.Draw(); }; playerList.Enter = (s, e) => { if (playerList.Items.Count == 0) { return; } //onLeft = false; var tryAttempt = TryStore(player, playerTokens[playerList.Index], playerItems[playerList.Index]); if (tryAttempt.IsBlank()) { containerItems.Add(playerItems[playerList.Index]); containerTokens.Add(playerTokens[playerList.Index]); containerList.Items.Add(playerList.Items[playerList.Index]); playerItems.RemoveAt(playerList.Index); playerTokens.RemoveAt(playerList.Index); playerList.Items.RemoveAt(playerList.Index); if (playerList.Index >= playerList.Items.Count) { playerList.Index--; } if (playerList.Items.Count == 0) { playerList.Hidden = true; keys[NoxicoGame.KeyBindings[KeyBinding.Left]] = true; } else { playerList.Height = (playerList.Items.Count < 10) ? playerList.Items.Count : 10; } containerList.Hidden = false; //always the case. containerList.Height = (containerList.Items.Count < 10) ? containerList.Items.Count : 10; containerWindow.Height = containerList.Height + 2; playerWindow.Height = playerList.Height + 2; capacity.Text = player.Character.Carried + "/" + player.Character.Capacity; if (mode == ContainerMode.Vendor) { capacity.Text = i18n.Format("inventory_money", vendorChar.Name.ToString(), vendorChar.GetToken("money").Value, player.Character.GetToken("money").Value); } playerList.Change(s, e); NoxicoGame.DrawStatus(); UIManager.Draw(); } else { //This is set by TryStore. if (vendorCaughtYou) { //Immediately break out of ContainerMan and call out. NoxicoGame.ClearKeys(); NoxicoGame.Immediate = true; NoxicoGame.Me.CurrentBoard.Redraw(); NoxicoGame.Me.CurrentBoard.Draw(true); NoxicoGame.Mode = UserMode.Walkabout; Subscreens.FirstDraw = true; SceneSystem.Engage(player.Character, vendorChar, "(criminalscum)"); } else { MessageBox.Notice(tryAttempt); } } }; } UIManager.Highlight = containerList.Items.Count > 0 ? containerList : playerList; UIManager.Draw(); if (UIManager.Highlight.Change != null) { UIManager.Highlight.Change(null, null); } Subscreens.FirstDraw = false; } if (NoxicoGame.IsKeyDown(KeyBinding.Back) || Vista.Triggers == XInputButtons.B) { NoxicoGame.ClearKeys(); NoxicoGame.Immediate = true; NoxicoGame.Me.CurrentBoard.Redraw(); NoxicoGame.Me.CurrentBoard.Draw(true); NoxicoGame.Mode = UserMode.Walkabout; Subscreens.FirstDraw = true; } else if (NoxicoGame.IsKeyDown(KeyBinding.Left)) { NoxicoGame.ClearKeys(); if (containerList.Items.Count == 0) { return; } UIManager.Highlight = containerList ?? playerList; containerList.DrawQuick(); containerList.Change(null, null); playerList.DrawQuick(); } else if (NoxicoGame.IsKeyDown(KeyBinding.Right)) { NoxicoGame.ClearKeys(); if (playerList.Items.Count == 0) { return; } UIManager.Highlight = playerList ?? containerList; playerList.Change(null, null); containerList.DrawQuick(); playerList.DrawQuick(); } else { UIManager.CheckKeys(); } }
public void Use(Character character, Token item, bool noConfirm = false) { var boardchar = NoxicoGame.Me.CurrentBoard.Entities.OfType <BoardChar>().First(x => x.Character == character); var runningDesc = string.Empty; Action <string> showDesc = new Action <string>(d => { NoxicoGame.DrawStatus(); if (d.Contains('\n')) { MessageBox.Notice(runningDesc.Viewpoint(boardchar.Character, null)); } else { NoxicoGame.AddMessage(runningDesc.Viewpoint(boardchar.Character, null)); } }); #region Books if (this.ID == "book") { TextScroller.ReadBook(item.GetToken("id").Text); return; } #endregion #region Equipment if (this.HasToken("equipable")) { if (item == null) { var items = character.GetToken("items"); item = items.Tokens.Find(x => x.Name == this.ID); } if (!item.HasToken("equipped")) { //TODO: only ask if it's the player? //Not wearing it MessageBox.Ask(runningDesc + i18n.Format("inventory_equip_x", this.ToString(item, true)), () => { try { if (this.Equip(character, item)) { runningDesc += i18n.Format("x_equiped_y", this.ToString(item, true)); } } catch (ItemException c) { runningDesc += c.Message; } if (!runningDesc.IsBlank()) { showDesc(runningDesc.Viewpoint(boardchar.Character)); } return; }, null); } else { //Wearing/wielding it if (item.HasToken("cursed") && item.GetToken("cursed").HasToken("known")) { runningDesc += item.GetToken("cursed").Text.IsBlank(i18n.Format("inventory_cursed_" + (this.HasToken("plural") ? "plural" : "singular"), this.ToString(item, true)), item.GetToken("cursed").Text); showDesc(runningDesc.Viewpoint(boardchar.Character)); return; } MessageBox.Ask(i18n.Format("inventory_unequip_x", this.ToString(item, true)), () => { try { if (this.Unequip(character)) { runningDesc += i18n.Format("x_unequiped_y", this.ToString(item, true)); } } catch (ItemException x) { runningDesc += x.Message; } if (!runningDesc.IsBlank()) { showDesc(runningDesc.Viewpoint(boardchar.Character)); } return; }, null); } return; } #endregion if (this.HasToken("ammo")) { MessageBox.Notice(i18n.GetString("thisisammo")); return; } if (this.HasToken("quest") || this.HasToken("nouse")) { if (this.HasToken("description")) { runningDesc = this.GetToken("description").Text + "\n\n"; } showDesc(runningDesc + i18n.GetString("noeffect")); return; } //Confirm use of potentially hazardous items if (!noConfirm) { var name = new StringBuilder(); if (this.IsProperNamed) { name.Append(this.Definite.IsBlank(string.Empty, this.Definite + ' ')); } else { name.Append(this.Indefinite.IsBlank(string.Empty, this.Indefinite + ' ')); } name.Append(this.Name); if (item.HasToken("unidentified") && !this.UnknownName.IsBlank()) { runningDesc = i18n.GetString("unidentified_warning"); } else { if (this.HasToken("description")) { //No need to check for "worn" or "examined" here... runningDesc = this.GetDescription(item) + "\n\n"; //this.GetToken("description").Text + "\n\n"; } runningDesc += i18n.Format("use_x_confirm", this.ToString(item, true)); } MessageBox.Ask(runningDesc, () => { this.Use(character, item, true); }, null); return; } var statBonus = this.GetToken("statbonus"); if (statBonus != null) { foreach (var bonus in statBonus.Tokens) { if (bonus.Name == "health") { character.Health += bonus.Value; if (character.Health > character.MaximumHealth) { character.Health = character.MaximumHealth; } } } } var food = this.GetToken("food"); if (food != null) { Eat(character, food); } if (!this.OnUse.IsBlank()) { RunScript(item, this.OnUse, character, boardchar, (x => runningDesc += x)); } else { this.Consume(character, item); } if (!runningDesc.IsBlank()) { showDesc(runningDesc.Viewpoint(boardchar.Character)); } }
public List <bool> Apply(Character target) { List <bool> returns = new List <bool>(); foreach (Token change in this.Tokens) { if (change.Name.StartsWith("!")) { change.Name = change.Name.Substring(1); foreach (Token checktoken in target.Tokens) { if (checktoken.Equals(change)) { target.RemoveToken(checktoken); returns.Add(true); break; } } returns.Add(false); } else { switch (change.Name) { case "deltaBreastSize": target.FixBoobs(); target.GetToken("breasts").GetToken("size").Value += change.GetToken("size").Value; returns.Add(true); break; case "deltaBreastNum": target.FixBoobs(); target.GetToken("breasts").GetToken("amount").Value += change.GetToken("amount").Value; returns.Add(true); break; case "dicknipples": target.FixBoobs(); var nips = target.GetToken("breasts").GetToken("nipples"); if (nips != null) { if (!nips.HasToken("canfuck")) { nips.RemoveToken("fuckable"); nips.RemoveToken("wetness"); nips.RemoveToken("looseness"); nips.AddToken("canfuck"); nips.AddToken("length", change.GetToken("length").Value); nips.AddToken("thickness", change.GetToken("thickness").Value); returns.Add(true); } else { returns.Add(false); } } else { returns.Add(false); } break; case "nipplecunts": nips = target.GetToken("breasts").GetToken("nipples"); if (nips != null) { if (!nips.HasToken("fuckable")) { nips.RemoveToken("canfuck"); nips.RemoveToken("length"); nips.RemoveToken("thickness"); nips.AddToken("fuckable"); nips.AddToken("wetness", change.GetToken("wetness").Value); nips.AddToken("looseness", change.GetToken("looseness").Value); returns.Add(true); } else { returns.Add(false); } } else { returns.Add(false); } break; case "deltaCockLength": if (target.HasToken("penis")) { target.GetToken("penis").GetToken("length").Value += change.GetToken("length").Value; returns.Add(true); } else { returns.Add(false); } break; case "deltaCockThickness": if (target.HasToken("penis")) { target.GetToken("penis").GetToken("thickness").Value += change.GetToken("thickness").Value; returns.Add(true); } else { returns.Add(false); } break; case "deltaNippleSize": target.FixBoobs(); if (target.GetToken("breasts").HasToken("nipples")) { target.GetToken("breasts").GetToken("nipples").GetToken("size").Value += change.GetToken("size").Value; returns.Add(true); } else { returns.Add(false); } break; case "deltaNippleNumber": target.FixBoobs(); var boobs = target.GetToken("breasts"); if (boobs.HasToken("nipples")) { boobs.GetToken("nipples").Value += change.GetToken("amount").Value; if (boobs.GetToken("nipples").Value <= 0) { boobs.RemoveToken("nipples"); } } else { boobs.AddToken("nipples", change.GetToken("amount").Value).AddToken("size", 0.5f); } returns.Add(true); break; case "taur": if (!target.HasToken("taur")) { target.AddToken("taur", (int)change.Value + target.GetToken("quadruped").Value); target.RemoveToken("snaketail"); target.RemoveToken("slimeblob"); target.RemoveToken("quadruped"); target.FixBroken(); returns.Add(true); } else { target.GetToken("taur").Value += (int)change.Value; if (target.GetToken("taur").Value <= 0) { target.RemoveToken("taur"); target.FixBroken(); } returns.Add(true); } break; case "snaketail": if (!target.HasToken("snaketail")) { target.RemoveToken("taur"); target.RemoveToken("slimeblob"); target.RemoveToken("quadruped"); target.AddToken("snaketail"); target.FixBroken(); returns.Add(true); } else { returns.Add(false); } break; case "quadruped": if (!target.HasToken("quadruped")) { target.AddToken("quadruped", change.Value + target.GetToken("taur").Value); target.RemoveToken("taur"); target.RemoveToken("slimeblob"); target.RemoveToken("snaketail"); target.FixBroken(); returns.Add(true); } else { target.GetToken("quadruped").Value += (int)change.Value; if (target.GetToken("quadruped").Value <= 0) { target.RemoveToken("quadruped"); target.FixBroken(); } returns.Add(true); } break; case "slimeblob": if (!target.HasToken("slimeblob")) { target.RemoveToken("taur"); target.RemoveToken("snaketail"); target.RemoveToken("quadruped"); target.AddToken("slimeblob"); target.FixBroken(); returns.Add(true); } else { returns.Add(false); } break; case "normalLegs": if (target.HasToken("taur") || target.HasToken("snaketail") || target.HasToken("slimeblob") || target.HasToken("quadruped")) { target.RemoveToken("taur"); target.RemoveToken("snaketail"); target.RemoveToken("quadruped"); target.RemoveToken("slimeblob"); target.FixBroken(); returns.Add(true); } else { returns.Add(false); } break; case "deltaBalls": if (target.HasToken("balls")) { target.GetToken("balls").GetToken("amount").Value += change.GetToken("amount").Value; returns.Add(true); } else { if (change.GetToken("amount").Value > 0) { target.AddToken("balls").AddToken("amount", (int)change.GetToken("amount").Value); returns.Add(true); } else { returns.Add(false); } } target.FixBroken(); break; case "deltaBallSize": if (target.HasToken("balls")) { target.GetToken("balls").GetToken("size").Value += change.GetToken("size").Value; target.FixBroken(); returns.Add(true); } else { returns.Add(false); } break; case "deltaEyes": target.GetToken("eyes").GetToken("count").Value += (int)change.GetToken("count").Value; returns.Add(true); break; case "legs": if (target.HasToken("legs")) { if (target.GetToken("legs").Text == change.Text) { returns.Add(false); } else { returns.Add(true); } target.GetToken("legs").Text = change.Text; } else { returns.Add(false); } break; default: target.AddToken(change); returns.Add(true); break; } } } return(returns); }
/// <summary> /// Returns a list of possible Recipes that a given character is able to craft. /// </summary> /// <param name="carrier">Probably the player character.</param> /// <returns>A list of possible recipes. Keep it, and invoke Apply on the player's choice.</returns> public static List <Recipe> GetPossibilities(Character carrier) { Carrier = carrier; ItemsToWorkWith = Carrier.GetToken("items"); var results = new List <Recipe>(); var tml = Mix.GetTokenTree("crafting.tml"); foreach (var recipe in tml) { var considered = new List <Token>(); var resultName = "?"; if (recipe.HasToken("produce")) { resultName = recipe.GetToken("produce").Text; } var resultingSourceItem = default(InventoryItem); var steps = recipe.Tokens; var stepRefs = new Token[steps.Count()]; var i = 0; var newRecipe = new Recipe(); foreach (var step in steps) { if (step.Name == "consume" || step.Name == "require") { var amount = 1; if (step.HasToken("amount")) { amount = (int)step.GetToken("amount").Value; } var numFound = 0; if (step.Text == "<anything>") { foreach (var carriedItem in ItemsToWorkWith.Tokens) { var knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == carriedItem.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", carriedItem.Name); continue; } var withs = step.GetAll("with"); var withouts = step.GetAll("withouts"); var okay = 0; foreach (var with in withs) { if (knownItem.HasToken(with.Text)) { okay++; } } foreach (var without in withouts) { if (knownItem.HasToken(without.Text)) { okay = 0; } } if (okay < withs.Count()) { continue; } if (carriedItem.HasToken("charge")) { numFound += (int)carriedItem.GetToken("charge").Value; } else { numFound++; } stepRefs[i] = carriedItem; if (i == 0) { resultingSourceItem = knownItem; } } } else if (step.Text == "book") { //TODO: see if a book with the given ID is marked as read. } else { foreach (var carriedItem in ItemsToWorkWith.Tokens.Where(t => t.Name == step.Text)) { var knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == carriedItem.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", carriedItem.Name); continue; } if (carriedItem.HasToken("charge")) { numFound += (int)carriedItem.GetToken("charge").Value; } else { numFound++; } stepRefs[i] = carriedItem; if (i == 0) { resultingSourceItem = knownItem; } } } if (numFound < amount) { Program.WriteLine("Crafting: not enough {0} to craft {1}.", step.Text, resultName); break; } if (step.Name == "consume") { newRecipe.Actions.Add(new CraftConsumeItemAction() { Target = stepRefs[i] }); } } else if (step.Name == "produce") { var itemMade = new Token(step.Text); itemMade.Tokens.AddRange(step.Tokens); newRecipe.Actions.Add(new CraftProduceItemAction() { Target = itemMade }); var resultingKnownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == itemMade.Name); newRecipe.Display = i18n.Format("craft_produce_x_from_y", resultingKnownItem.ToString(itemMade), resultingSourceItem.ToString(stepRefs[0])); } else if (step.Name == "train") { newRecipe.Actions.Add(new CraftTrainAction() { Trainee = carrier, Target = step }); } } if (newRecipe.Display.IsBlank()) { continue; } if (results.Exists(x => x.Display == newRecipe.Display)) { continue; } results.Add(newRecipe); } //Find dyes foreach (var maybeDye in ItemsToWorkWith.Tokens) { var knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == maybeDye.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", maybeDye.Name); continue; } if (knownItem.HasToken("dye")) { var dyeItem = maybeDye; var color = dyeItem.GetToken("color").Text; foreach (var carriedItem in ItemsToWorkWith.Tokens) { knownItem = NoxicoGame.KnownItems.Find(ki => ki.ID == carriedItem.Name); if (knownItem == null) { Program.WriteLine("Crafting: don't know what a {0} is.", carriedItem.Name); continue; } if (knownItem.HasToken("colored") && !knownItem.HasToken("dye")) { var newRecipe = new Recipe(); newRecipe.Display = i18n.Format("craft_dye_x_y", knownItem.ToString(carriedItem), color); if (!carriedItem.HasToken("color")) { newRecipe.Actions.Add(new CraftAddTokenAction() { Target = carriedItem, Add = new Token("color", 0, color) }); } else if (carriedItem.GetToken("color").Text == color) { continue; } else { newRecipe.Actions.Add(new CraftChangeTokenAction() { Target = carriedItem.GetToken("color"), NewText = color, NewValue = 0 }); } results.Add(newRecipe); } } } } return(results); }