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 * } */ }