public object RunScript(Token item, string script, Character character, BoardChar boardchar, Action <string> running) { var env = Lua.Environment; env.user = character; env.thisItem = this; env.thisToken = item; env.Consume = new Action <string>(x => this.Consume(character, item) /* character.GetToken("items").Tokens.Remove(item) */); env.print = new Action <string, bool>((x, y) => { var paused = true; MessageBox.ScriptPauseHandler = () => { paused = false; }; MessageBox.Notice((y ? x : x.Viewpoint(character)), true); while (paused) { NoxicoGame.Me.Update(); System.Windows.Forms.Application.DoEvents(); } }); env.ReportSet = new Action <List <string> >(x => { foreach (var result in x) { if (!result.IsBlank() && result[0] != '\uE2FC') { NoxicoGame.AddMessage(result.Viewpoint(character)); } } }); env.Identify = new Action <string>(x => { if (character.GetStat("mind") < 10) { //Dumb characters can't identify as well. if (Random.NextDouble() < 0.5) { return; } } //Random potion identification /* * if (this.HasToken("randomized")) * { * var rid = (int)this.GetToken("randomized").Value; * if (this.Path("equipable/ring") != null && rid < 128) * rid += 128; * var rdesc = NoxicoGame.Me.Potions[rid]; * if (rdesc[0] != '!') * { * //Still unidentified. Let's rock. * rdesc = '!' + rdesc; * NoxicoGame.Me.Potions[rid] = rdesc; * this.UnknownName = null; * } * //Random potions and rings are un-unidentified by taking away their UnknownName, but we clear the unidentified state anyway. * //item.RemoveToken("unidentified"; * //runningDesc += "You have identified this as " + this.ToString(item, true) + "."; * //return; * } */ //Regular item identification if (!this.UnknownName.IsBlank() && !NoxicoGame.Identifications.Contains(this.ID)) { NoxicoGame.Identifications.Add(this.ID); if (running != null) { running(i18n.Format("inventory_identify_as_x", this.ToString(item, true))); } } }); //var ret = env.DoChunk(script, "lol.lua"); return(Lua.Run(script, env)); }
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 static void Apply(Token result, Character actor, Character target, Action <string> writer) { if (!result.HasToken("effect")) { return; } var f = result.GetToken("effect"); var script = f.Tokens.Count == 1 ? f.Tokens[0].Text : f.Text; var env = Lua.Environment; env.top = actor; env.bottom = target; env.consentual = !target.HasToken("helpless"); env.nonconsentual = target.HasToken("helpless"); env.masturbating = actor == target; env.MessageR = new Action <object, Color>((x, y) => { if (x is Neo.IronLua.LuaTable) { x = ((Neo.IronLua.LuaTable)x).ArrayList.ToArray(); } while (x is object[]) { var options = (object[])x; x = options.PickOne(); if (x is Neo.IronLua.LuaTable) { x = ((Neo.IronLua.LuaTable)x).ArrayList.ToArray(); } } NoxicoGame.AddMessage(ApplyMemory(x.ToString()).Viewpoint(actor, target), y); }); env.Stop = new Action(() => { actor.RemoveAll("havingsex"); target.RemoveAll("havingsex"); }); env.Roll = new Func <object, object, bool>((x, y) => { float a, b; if (!float.TryParse(x.ToString(), out a)) { if (Character.StatNames.Contains(x.ToString().ToLowerInvariant())) { a = actor.GetStat(x.ToString()); } else { a = actor.GetSkillLevel(x.ToString()); } } if (!float.TryParse(y.ToString(), out b)) { if (Character.StatNames.Contains(x.ToString().ToLowerInvariant())) { b = actor.GetStat(x.ToString()); } else { b = target.GetSkillLevel(y.ToString()); } } return(a >= b); }); // Okay, Sparky. What I did was, I put all the error handling in Lua.cs, with a Run method. // Instead of worrying about presentation, it just uses a standard WinForms MessageBox. // After all, the game's already in a broken state by now. var msg = env.Message; env.Message = new Action <object, object>((x, y) => { if (x is Neo.IronLua.LuaTable) { x = ((Neo.IronLua.LuaTable)x).ArrayList.ToArray(); } while (x is object[]) { var options = (object[])x; x = options.PickOne(); if (x is Neo.IronLua.LuaTable) { x = ((Neo.IronLua.LuaTable)x).ArrayList.ToArray(); } } NoxicoGame.AddMessage(ApplyMemory(x.ToString()).Viewpoint(actor, target), y); }); Lua.Run(script, env); env.Message = msg; /* * try * { * // really should just compile once at startup but we're just testing the debugger trace * // anyway here's how you'd do it. * //LuaChunk chunk = env.Lua.CompileChunk(script, "lol.lua", new LuaStackTraceDebugger()); * //env.DoChunk(chunk, "lol.lua"); * env.DoChunk(script, "lol.lua"); * } * catch (Neo.IronLua.LuaParseException lpe) * { * string complain = String.Format("Exception: {0} line {1} col {2},\r\n", * lpe.Message, lpe.Line, lpe.Column); * * LuaExceptionData lex = LuaExceptionData.GetData(lpe); * foreach (LuaStackFrame lsf in lex) * { * complain += String.Format("StackTrace: {0} line {1} col {2},\r\n", * lsf.MethodName, lsf.LineNumber, lsf.ColumnNumber); * } * * var paused = true; * MessageBox.ScriptPauseHandler = () => paused = false; * MessageBox.Notice(complain); * while (paused) * { * NoxicoGame.Me.Update(); * System.Windows.Forms.Application.DoEvents(); * } * // kawa! things get REALLY BROKEN at this point but at least you got a MessageBox -- sparks * } */ }