public static void AtStartup(RuleEngine GlobalRules) { Core.StandardMessage("say what", "Say what?"); Core.StandardMessage("emote what", "You exist. Actually this is an error message, but that's what you just told me to say."); Core.StandardMessage("speak", "^<the0> : \"<s1>\""); Core.StandardMessage("emote", "^<the0> <s1>"); GlobalRules.DeclarePerformRuleBook <MudObject, String>("speak", "[Actor, Text] : Handle the actor speaking the text.", "actor", "text"); GlobalRules.Perform <MudObject, String>("speak") .Do((actor, text) => { Core.SendLocaleMessage(actor, "@speak", actor, text); return(PerformResult.Continue); }) .Name("Default motormouth rule."); GlobalRules.DeclarePerformRuleBook <MudObject, String>("emote", "[Actor, Text] : Handle the actor emoting the text.", "actor", "text"); GlobalRules.Perform <MudObject, String>("emote") .Do((actor, text) => { Core.SendLocaleMessage(actor, "@emote", actor, text); return(PerformResult.Continue); }) .Name("Default exhibitionist rule."); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook <PossibleMatch, MudObject>("before command", "[Match, Actor] : Considered before every command's procedural rules are run.", "match", "actor"); GlobalRules.DeclarePerformRuleBook <PossibleMatch, MudObject>("after command", "[Match, Actor] : Considered after every command's procedural rules are run, unless the before command rules stopped the command.", "match", "actor"); GlobalRules.DeclarePerformRuleBook <MudObject>("after every command", "[Actor] : Considered after every command, even if earlier rules stopped the command.", "actor"); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook <Actor>("player joined", "[Player] : Considered when a player enters the game.", "actor"); GlobalRules.DeclarePerformRuleBook <Actor>("player left", "[Player] : Considered when a player leaves the game.", "actor"); GlobalRules.Perform <Actor>("player joined") .First .Do((actor) => { MudObject.Move(actor, MudObject.GetObject(Core.SettingsObject.NewPlayerStartRoom)); return(PerformResult.Continue); }) .Name("Move to start room rule."); }
public static void AtStartup(RuleEngine GlobalRules) { Core.StandardMessage("carrying", "You are carrying.."); GlobalRules.DeclarePerformRuleBook <MudObject>("inventory", "[Actor] : Describes a player's inventory to themselves.", "actor"); GlobalRules.Perform <MudObject>("inventory") .Do(a => { var heldObjects = a.GetContents(RelativeLocations.HELD); if (heldObjects.Count == 0) { Core.SendMessage(a, "@empty handed", a); } else { Core.SendMessage(a, "@carrying"); foreach (var item in heldObjects) { Core.SendMessage(a, " <a0>", item); } } return(PerformResult.Continue); }) .Name("List held items in inventory rule."); }
/// <summary> /// Start the mud engine. /// </summary> /// <param name="Flags">Flags control engine functions</param> /// <param name="Database"></param> /// <param name="Assemblies">Modules to integrate</param> /// <returns></returns> public static bool Start(StartupFlags Flags, String DatabasePath, WorldDataService Database, Assembly AdditionalAssembly = null) { Core.DatabasePath = DatabasePath; ShuttingDown = false; Core.Flags = Flags; try { // Setup the rule engine and some basic rules. GlobalRules = new RuleEngine(NewRuleQueueingMode.QueueNewRules); GlobalRules.DeclarePerformRuleBook("at startup", "[] : Considered when the engine is started."); GlobalRules.DeclarePerformRuleBook <MudObject>("singleplayer game started", "Considered when a single player game is begun"); DefaultParser = new CommandParser(); InitializeEngine(Assembly.GetExecutingAssembly()); if (AdditionalAssembly != null) { InitializeEngine(AdditionalAssembly); } InitializeCommandProcessor(); GlobalRules.FinalizeNewRules(); Core.Database = Database; Database.Initialize(); GlobalRules.ConsiderPerformRule("at startup"); if ((Flags & StartupFlags.SingleThreaded) == 0) { StartThreadedCommandProcesor(); } } catch (Exception e) { LogError("Failed to start mud engine."); LogError(e.Message); LogError(e.StackTrace); throw; } return(true); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook("heartbeat", "[] : Considered every tick."); GlobalRules.Perform("heartbeat").Do(() => { MudObject.TimeOfDay += Core.SettingsObject.ClockAdvanceRate; return(PerformResult.Continue); }).Name("Advance clock on heartbeat rule"); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("you unlock", "You unlock <the0>."); Core.StandardMessage("they unlock", "^<the0> unlocks <the1> with <a2>."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject, MudObject>("unlocked", "[Actor, Item, Key] : Handle the actor unlocking the item with the key.", "actor", "item", "key"); GlobalRules.Perform <MudObject, MudObject, MudObject>("unlocked").Do((actor, target, key) => { Core.SendMessage(actor, "@you unlock", target); Core.SendExternalMessage(actor, "@they unlock", actor, target, key); return(PerformResult.Continue); }); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("you drop", "You drop <the0>."); Core.StandardMessage("they drop", "^<the0> drops <a1>."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can drop?", "[Actor, Item] : Determine if the item can be dropped.", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("drop", "[Actor, Item] : Handle an item being dropped.", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can drop?") .First .When((actor, item) => !Core.ObjectContainsObject(actor, item)) .Do((actor, item) => { Core.SendMessage(actor, "@dont have that"); return(CheckResult.Disallow); }) .Name("Must be holding it to drop it rule."); GlobalRules.Check <MudObject, MudObject>("can drop?") .First .When((actor, item) => actor.Contains(item, RelativeLocations.WORN)) .Do((actor, item) => { if (GlobalRules.ConsiderCheckRule("can remove?", actor, item) == CheckResult.Allow) { GlobalRules.ConsiderPerformRule("remove", actor, item); return(CheckResult.Continue); } return(CheckResult.Disallow); }) .Name("Dropping worn items follows remove rules rule."); GlobalRules.Check <MudObject, MudObject>("can drop?").Do((a, b) => CheckResult.Allow).Name("Default can drop anything rule."); GlobalRules.Perform <MudObject, MudObject>("drop").Do((actor, target) => { Core.SendMessage(actor, "@you drop", target); Core.SendExternalMessage(actor, "@they drop", actor, target); if (actor.Location.HasValue(out var loc)) { Core.Move(target, loc); } return(PerformResult.Continue); }).Name("Default drop handler rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("you close", "You close <the0>."); Core.StandardMessage("they close", "^<the0> closes <the1>."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can close?", "[Actor, Item] : Determine if the item can be closed.", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("close", "[Actor, Item] : Handle the item being closed.", "actor", "item"); GlobalRules.Perform <MudObject, MudObject>("close").Do((actor, target) => { target.SetProperty("open?", false); Core.SendMessage(actor, "@you close", target); Core.SendExternalMessage(actor, "@they close", actor, target); return(PerformResult.Continue); }).Name("Default close reporting rule."); GlobalRules.Check <MudObject, MudObject>("can close?").First.Do((actor, item) => Core.CheckIsVisibleTo(actor, item)).Name("Item must be visible rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can wear?", "[Actor, Item] : Can the actor wear the item?", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("worn", "[Actor, Item] : Handle the actor wearing the item.", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can wear?") .When((a, b) => !Core.ObjectContainsObject(a, b)) .Do((actor, item) => { Core.SendMessage(actor, "@dont have that"); return(CheckResult.Disallow); }); GlobalRules.Check <MudObject, MudObject>("can wear?") .When((a, b) => a.RelativeLocationOf(b) == RelativeLocations.WORN) .Do((a, b) => { Core.SendMessage(a, "@clothing already wearing"); return(CheckResult.Disallow); }); GlobalRules.Check <MudObject, MudObject>("can wear?") .When((actor, item) => !item.GetProperty <bool>("wearable?")) .When((actor, item) => !actor.GetProperty <bool>("actor?")) .Do((actor, item) => { Core.SendMessage(actor, "@clothing cant wear"); return(CheckResult.Disallow); }) .Name("Can't wear unwearable things rule."); GlobalRules.Check <MudObject, MudObject>("can wear?").Do((a, b) => CheckResult.Allow); GlobalRules.Perform <MudObject, MudObject>("worn").Do((actor, target) => { Core.SendMessage(actor, "@clothing you wear", target); Core.SendExternalMessage(actor, "@clothing they wear", actor, target); Core.Move(target, actor, RelativeLocations.WORN); return(PerformResult.Continue); }); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { PropertyManifest.RegisterProperty("lockable?", typeof(bool), false, new BoolSerializer()); Core.StandardMessage("not lockable", "I don't think the concept of 'locked' applies to that."); Core.StandardMessage("you lock", "You lock <the0>."); Core.StandardMessage("they lock", "^<the0> locks <the1> with <the2>."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject, MudObject>("can lock?", "[Actor, Item, Key] : Can the item be locked by the actor with the key?", "actor", "item", "key"); GlobalRules.Check <MudObject, MudObject, MudObject>("can lock?") .Do((actor, item, key) => Core.CheckIsVisibleTo(actor, item)) .Name("Item must be visible to lock it."); GlobalRules.Check <MudObject, MudObject, MudObject>("can lock?") .Do((actor, item, key) => Core.CheckIsHolding(actor, key)) .Name("Key must be held rule."); GlobalRules.Check <MudObject, MudObject, MudObject>("can lock?") .When((actor, item, key) => !item.GetProperty <bool>("lockable?")) .Do((a, b, c) => { Core.SendMessage(a, "@not lockable"); return(CheckResult.Disallow); }) .Name("Can't lock the unlockable rule."); GlobalRules.Check <MudObject, MudObject, MudObject>("can lock?") .Do((a, b, c) => CheckResult.Allow) .Name("Default allow locking rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject, MudObject>("locked", "[Actor, Item, Key] : Handle the actor locking the item with the key.", "actor", "item", "key"); GlobalRules.Perform <MudObject, MudObject, MudObject>("locked").Do((actor, target, key) => { Core.SendMessage(actor, "@you lock", target); Core.SendExternalMessage(actor, "@they lock", actor, target, key); return(PerformResult.Continue); }); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can attack?", "[Actor, Other] : Can the actor the other?", "actor", "other"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("attack", "[Actor, Other] : Handle the actor the other.", "actor", "other"); GlobalRules.Check <MudObject, MudObject>("can attack?").Do((a, b) => CheckResult.Allow).Name("Can attack anything by default rule."); GlobalRules.Perform <MudObject, MudObject>("attack").Do((actor, target) => { // Weapon? if (target.HasProperty("combat health")) { actor.SetProperty("combat target", target); } else { Core.SendMessage(actor, "@you attack uselessly", actor, target); Core.SendExternalMessage(actor, "@they attack uselessly", actor, target); } return(PerformResult.Continue); }); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook <MudObject>("update", "[Thing] : Considered for all things that have been marked for update.", "item"); GlobalRules.Perform <Actor>("after every command") .First .Do((actor) => { Core.UpdateMarkedObjects(); return(PerformResult.Continue); }) .Name("Update marked objects at end of turn rule."); GlobalRules.Perform <Actor>("after every command") .Last .Do((actor) => { Core.SendPendingMessages(); return(PerformResult.Continue); }) .Name("Send pending messages at end of turn rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("not openable", "I don't think the concept of 'open' applies to that."); Core.StandardMessage("you open", "You open <the0>."); Core.StandardMessage("they open", "^<the0> opens <the1>."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can open?", "[Actor, Item] : Can the actor open the item?", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("opened", "[Actor, Item] : Handle the actor opening the item.", "actor", "item"); GlobalRules.Perform <MudObject, MudObject>("opened").Do((actor, target) => { target.SetProperty("open?", true); Core.SendMessage(actor, "@you open", target); Core.SendExternalMessage(actor, "@they open", actor, target); return(PerformResult.Continue); }).Name("Default report opening rule."); GlobalRules.Check <MudObject, MudObject>("can open?").First.Do((actor, item) => Core.CheckIsVisibleTo(actor, item)).Name("Item must be visible rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can remove?", "[Actor, Item] : Can the actor remove the item?", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("removed", "[Actor, Item] : Handle the actor removing the item.", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can remove?") .When((a, b) => !a.Contains(b, RelativeLocations.WORN)) .Do((actor, item) => { Core.SendMessage(actor, "@clothing not wearing"); return(CheckResult.Disallow); }); GlobalRules.Check <MudObject, MudObject>("can remove?").Do((a, b) => CheckResult.Allow); GlobalRules.Perform <MudObject, MudObject>("removed").Do((actor, target) => { Core.SendMessage(actor, "@clothing you remove", target); Core.SendExternalMessage(actor, "@clothing they remove", actor, target); Core.Move(target, actor, RelativeLocations.HELD); return(PerformResult.Continue); }); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can pull?", "[Actor, Item] : Can the actor pull the item?", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("pull", "[Actor, Item] : Handle the actor pulling the item.", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can pull?") .Do((actor, item) => Core.CheckIsVisibleTo(actor, item)) .Name("Item must be visible to pull rule."); GlobalRules.Check <MudObject, MudObject>("can pull?") .Last .Do((a, t) => { Core.SendMessage(a, "@does nothing"); return(CheckResult.Disallow); }) .Name("Default disallow pulling rule."); GlobalRules.Perform <MudObject, MudObject>("pull") .Do((actor, target) => { Core.SendMessage(actor, "@nothing happens"); return(PerformResult.Continue); }) .Name("Default handle pulling rule."); GlobalRules.Check <MudObject, MudObject>("can pull?") .First .When((actor, target) => target.GetProperty <bool>("actor?")) .Do((actor, thing) => { Core.SendMessage(actor, "@unappreciated", thing); return(CheckResult.Disallow); }) .Name("Can't pull people rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can wield?", "[Actor, Item] : Can the actor wield the item?", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("wield", "[Actor, Item] : Handle the actor wielding the item.", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can wield?").Do((a, b) => CheckResult.Allow).Name("Improvised weapon rule."); GlobalRules.Check <MudObject, MudObject>("can wield?") .When((a, b) => !Core.ObjectContainsObject(a, b)) .Do((actor, item) => { Core.SendMessage(actor, "@dont have that"); return(CheckResult.Disallow); }) .Name("Can't wield what you don't have rule."); GlobalRules.Perform <MudObject, MudObject>("wield").Do((actor, target) => { actor.SetProperty("combat weapon", target); Core.SendMessage(actor, "@you wield", actor, target); Core.SendExternalMessage(actor, "@they wield", actor, target); return(PerformResult.Continue); }); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook <PossibleMatch, Actor>("before acting", "[Match, Actor] : Considered before performing in world actions."); GlobalRules.DeclarePerformRuleBook <PossibleMatch, Actor>("after acting", "[Match, Actor] : Considered after performing in world actions."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("cant put relloc", "You can't put things <s0> that."); Core.StandardMessage("you put", "You put <the0> <s1> <the2>."); Core.StandardMessage("they put", "^<the0> puts <the1> <s2> <the3>."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject, MudObject, RelativeLocations>("can put?", "[Actor, Item, Container, Location] : Determine if the actor can put the item in or on or under the container.", "actor", "item", "container", "relloc"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject, MudObject, RelativeLocations>("put", "[Actor, Item, Container, Location] : Handle an actor putting the item in or on or under the container.", "actor", "item", "container", "relloc"); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .Last .Do((a, b, c, d) => CheckResult.Allow) .Name("Allow putting as default rule."); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .Do((actor, item, container, relloc) => { if (!(container.GetProperty <bool>("container?"))) { Core.SendMessage(actor, "@cant put relloc", Relloc.GetRelativeLocationName(relloc)); return(CheckResult.Disallow); } return(CheckResult.Continue); }) .Name("Can't put things in things that aren't containers rule."); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .Do((actor, item, container, relloc) => { if (GlobalRules.ConsiderCheckRule("can drop?", actor, item) != CheckResult.Allow) { return(CheckResult.Disallow); } return(CheckResult.Continue); }) .Name("Putting is dropping rule."); GlobalRules.Perform <MudObject, MudObject, MudObject, RelativeLocations>("put") .Do((actor, item, container, relloc) => { Core.SendMessage(actor, "@you put", item, Relloc.GetRelativeLocationName(relloc), container); Core.SendExternalMessage(actor, "@they put", actor, item, Relloc.GetRelativeLocationName(relloc), container); Core.Move(item, container, relloc); return(PerformResult.Continue); }) .Name("Default putting things in things handler."); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .Do((actor, item, container, relloc) => { if ((container.ContentLocationsAllowed & relloc) != relloc) { Core.SendMessage(actor, "@cant put relloc", Relloc.GetRelativeLocationName(relloc)); return(CheckResult.Disallow); } return(CheckResult.Continue); }) .Name("Check supported locations before putting rule."); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .Do((actor, item, container, relloc) => { if (relloc == RelativeLocations.IN && !container.GetProperty <bool>("open?")) { Core.SendMessage(actor, "@is closed error", container); return(CheckResult.Disallow); } return(CheckResult.Continue); }) .Name("Can't put things in closed container rule."); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .First .Do((actor, item, container, relloc) => Core.CheckIsVisibleTo(actor, container)) .Name("Container must be visible rule."); GlobalRules.Check <MudObject, MudObject, MudObject, RelativeLocations>("can put?") .First .Do((actor, item, container, relloc) => Core.CheckIsHolding(actor, item)) .Name("Must be holding item rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("is open", "^<the0> is open."); Core.StandardMessage("is closed", "^<the0> is closed."); Core.StandardMessage("describe on", "On <the0> is <l1>."); Core.StandardMessage("describe in", "In <the0> is <l1>."); Core.StandardMessage("empty handed", "^<the0> is empty handed."); Core.StandardMessage("holding", "^<the0> is holding <l1>."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("describe", "[Actor, Item] : Generates descriptions of the item.", "actor", "item"); GlobalRules.Perform <MudObject, MudObject>("describe") .When((viewer, item) => !String.IsNullOrEmpty(item.GetProperty <String>("long"))) .Do((viewer, item) => { Core.SendMessage(viewer, item.GetProperty <String>("long")); return(PerformResult.Continue); }) .Name("Basic description rule."); GlobalRules.Perform <MudObject, MudObject>("describe") .When((viewer, item) => item.GetProperty <bool>("openable?")) .Do((viewer, item) => { if (item.GetProperty <bool>("open?")) { Core.SendMessage(viewer, "@is open", item); } else { Core.SendMessage(viewer, "@is closed", item); } return(PerformResult.Continue); }) .Name("Describe open or closed state rule."); GlobalRules.Perform <MudObject, MudObject>("describe") .When((viewer, item) => (item.ContentLocationsAllowed & RelativeLocations.ON) == RelativeLocations.ON) .Do((viewer, item) => { var contents = item.GetContents(RelativeLocations.ON); if (contents.Count() > 0) { Core.SendMessage(viewer, "@describe on", item, contents); } return(PerformResult.Continue); }) .Name("List things on container in description rule."); GlobalRules.Perform <MudObject, MudObject>("describe") .When((viewer, item) => { if (item.GetProperty <bool>("container?")) { return(false); } if (!item.GetProperty <bool>("open?")) { return(false); } if (item.EnumerateObjects(RelativeLocations.IN).Count() == 0) { return(false); } return(true); }) .Do((viewer, item) => { var contents = item.GetContents(RelativeLocations.IN); if (contents.Count() > 0) { Core.SendMessage(viewer, "@describe in", item, contents); } return(PerformResult.Continue); }) .Name("List things in open container in description rule."); GlobalRules.Perform <MudObject, MudObject>("describe") .First .When((viewer, actor) => actor.GetProperty <bool>("actor?")) .Do((viewer, actor) => { var heldItems = new List <MudObject>(actor.EnumerateObjects(RelativeLocations.HELD)); if (heldItems.Count == 0) { Core.SendMessage(viewer, "@empty handed", actor); } else { Core.SendMessage(viewer, "@holding", actor, heldItems); } return(PerformResult.Continue); }) .ID("list-actor-held-items-rule") .Name("List held items when describing an actor rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { PropertyManifest.RegisterProperty("active-quest", typeof(MudObject), null, new DefaultSerializer()); PropertyManifest.RegisterProperty("offered-quest", typeof(MudObject), null, new DefaultSerializer()); GlobalRules.Perform <PossibleMatch, MudObject>("after acting") .Do((match, actor) => { if (actor.GetProperty <MudObject>("active-quest") != null) { var quest = actor.GetProperty <MudObject>("active-quest"); if (GlobalRules.ConsiderValueRule <bool>("quest complete?", actor, quest)) { actor.SetProperty("active-quest", null); GlobalRules.ConsiderPerformRule("quest completed", actor, quest); } else if (GlobalRules.ConsiderValueRule <bool>("quest failed?", actor, quest)) { actor.SetProperty("active-quest", null); GlobalRules.ConsiderPerformRule("quest failed", actor, quest); } } return(PerformResult.Continue); }) .Name("Check quest status after acting rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("quest reset", "[quest, thing] : The quest is being reset. Quests can call this on objects they interact with.", "quest", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("quest accepted", "[actor, quest] : Handle accepting a quest.", "actor", "quest"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("quest completed", "[actor, quest] : Handle when a quest is completed.", "actor", "quest"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("quest failed", "[actor, quest] : Handle when a quest is failed.", "actor", "quest"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("quest abandoned", "[actor, quest] : Handle when a quest is abandoned.", "actor", "quest"); GlobalRules.Perform <MudObject, MudObject>("quest abandoned") .Last .Do((actor, quest) => { return(GlobalRules.ConsiderPerformRule("quest failed", actor, quest)); }) .Name("Abandoning a quest is failure rule."); GlobalRules.DeclareValueRuleBook <MudObject, MudObject, bool>("quest available?", "[actor, quest -> bool] : Is the quest available to this actor?", "actor", "quest"); GlobalRules.Value <MudObject, MudObject, bool>("quest available?") .Do((Actor, quest) => false) .Name("Quests unavailable by default rule."); GlobalRules.DeclareValueRuleBook <MudObject, MudObject, bool>("quest complete?", "[actor, quest -> bool] : Has this actor completed this quest?", "actor", "quest"); GlobalRules.Value <MudObject, MudObject, bool>("quest complete?") .Do((actor, quest) => false) .Name("Quests incomplete by default rule."); GlobalRules.DeclareValueRuleBook <MudObject, MudObject, bool>("quest failed?", "[actor, quest -> bool] : Has this actor failed this quest?", "actor", "quest"); GlobalRules.Value <MudObject, MudObject, bool>("quest failed?") .Do((actor, quest) => false) .Name("Quests can't fail by default rule."); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook <MudObject, String>("stats", "[Actor, Type] : Display engine stats."); GlobalRules.DeclarePerformRuleBook <MudObject>("enumerate-stats", "[Actor] : Display stats options."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { PropertyManifest.RegisterProperty("combat weapon", typeof(MudObject), null, new DefaultSerializer()); PropertyManifest.RegisterProperty("combat health", typeof(int), 0, new IntSerializer()); PropertyManifest.RegisterProperty("combat damage die", typeof(String), "", new StringSerializer()); PropertyManifest.RegisterProperty("combat hit modifier", typeof(int), 0, new IntSerializer()); PropertyManifest.RegisterProperty("combat armor class", typeof(int), 0, new IntSerializer()); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("attacked", "[Attacker, Target] => Attacker Attacked Target rule.", "Attacker", "Target"); GlobalRules.Perform <MudObject>("inventory") .When(a => a.GetProperty <MudObject>("combat weapon") != null) .Do(a => { Core.SendMessage(a, "@wielding", a, a.GetProperty <MudObject>("combat weapon")); return(PerformResult.Continue); }) .Name("List weapon in inventory rule."); GlobalRules.Perform <MudObject, MudObject>("drop") .First .When((actor, target) => Object.ReferenceEquals(actor.GetProperty <MudObject>("combat weapon"), target)) .Do((actor, target) => { actor.SetProperty("combat weapon", null); return(PerformResult.Continue); }).Name("Unwield dropped item rule"); GlobalRules.Perform <MudObject, MudObject>("describe") .When((viewer, item) => item.GetProperty <MudObject>("combat weapon") != null) .Do((viewer, item) => { Core.SendMessage(viewer, "@wielding", item, item.GetProperty <MudObject>("combat weapon")); return(PerformResult.Continue); }) .Name("Describe their weapon rule."); GlobalRules.Perform <MudObject>("heartbeat") .When(o => o.HasProperty("combat target") && o.GetProperty <MudObject>("combat target") != null) .Do((o) => { var target = o.GetProperty <MudObject>("combat target"); if (target == null || target.State == ObjectState.Destroyed) { o.SetProperty("combat target", null); return(PerformResult.Continue); } if (!Core.IsVisibleTo(o, target)) { Core.SendMessage(o, "Your target is no longer here."); o.SetProperty("combat target", null); return(PerformResult.Continue); } CombatSystem.MeleeAttack(o, target); GlobalRules.ConsiderPerformRule("attacked", o, target); return(PerformResult.Continue); }) .Name("I'm in a fight, I'd better attack rule."); GlobalRules.Perform <MudObject, MudObject>("attacked") .Do((attacker, target) => { target.SetProperty("combat target", attacker); return(PerformResult.Continue); }) .Name("fight back rule"); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { Core.StandardMessage("you take", "You take <the0>."); Core.StandardMessage("they take", "^<the0> takes <the1>."); Core.StandardMessage("cant take people", "You can't take people."); Core.StandardMessage("cant take portals", "You can't take portals."); Core.StandardMessage("cant take scenery", "That's a terrible idea."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can take?", "[Actor, Item] : Can the actor take the item?", "actor", "item"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("take", "[Actor, Item] : Handle the actor taking the item.", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can take?") .Do((actor, item) => Core.CheckIsVisibleTo(actor, item)) .Name("Item must be visible to take rule."); GlobalRules.Check <MudObject, MudObject>("can take?") .When((actor, item) => actor.Contains(item, RelativeLocations.HELD)) .Do((actor, item) => { Core.SendMessage(actor, "@already have that"); return(CheckResult.Disallow); }) .Name("Can't take what you're already holding rule."); GlobalRules.Check <MudObject, MudObject>("can take?") .Last .Do((a, t) => CheckResult.Allow) .Name("Default allow taking rule."); GlobalRules.Perform <MudObject, MudObject>("take") .Do((actor, target) => { Core.SendMessage(actor, "@you take", target); Core.SendExternalMessage(actor, "@they take", actor, target); Core.Move(target, actor); return(PerformResult.Continue); }) .Name("Default handle taken rule."); GlobalRules.Check <MudObject, MudObject>("can take?") .First .When((actor, thing) => thing.GetProperty <bool>("actor?")) .Do((actor, thing) => { Core.SendMessage(actor, "@cant take people"); return(CheckResult.Disallow); }) .Name("Can't take people rule."); GlobalRules.Check <MudObject, MudObject>("can take?") .First .When((actor, thing) => thing.GetProperty <bool>("portal?")) .Do((actor, thing) => { Core.SendMessage(actor, "@cant take portals"); return(CheckResult.Disallow); }); GlobalRules.Check <MudObject, MudObject>("can take?") .First .When((actor, thing) => thing.GetProperty <bool>("scenery?")) .Do((actor, thing) => { Core.SendMessage(actor, "@cant take scenery"); return(CheckResult.Disallow); }) .Name("Can't take scenery rule."); }
/// <summary> /// Start the mud engine. /// </summary> /// <param name="Flags">Flags control engine functions</param> /// <param name="Database"></param> /// <param name="Assemblies">Modules to integrate</param> /// <returns></returns> public static bool Start(StartupFlags Flags, WorldDataService Database, params ModuleAssembly[] Assemblies) { ShuttingDown = false; Core.Flags = Flags; try { // Setup the rule engine and some basic rules. GlobalRules = new RuleEngine(NewRuleQueueingMode.QueueNewRules); GlobalRules.DeclarePerformRuleBook("at startup", "[] : Considered when the engine is started."); GlobalRules.DeclarePerformRuleBook <MudObject>("singleplayer game started", "Considered when a single player game is begun"); // Integrate modules. The Core assembly is always integrated. IntegratedModules.Add(new ModuleAssembly(Assembly.GetExecutingAssembly(), new ModuleInfo { Author = "Blecki", Description = "RMUD Core", BaseNameSpace = "RMUD" }, "Core.dll")); IntegratedModules.AddRange(Assemblies); if ((Flags & StartupFlags.SearchDirectory) == StartupFlags.SearchDirectory) { foreach (var file in System.IO.Directory.EnumerateFiles(System.IO.Directory.GetCurrentDirectory()).Where(p => System.IO.Path.GetExtension(p) == ".dll")) { var assembly = System.Reflection.Assembly.LoadFrom(file); var infoType = assembly.GetTypes().FirstOrDefault(t => t.IsSubclassOf(typeof(ModuleInfo))); if (infoType != null) { IntegratedModules.Add(new ModuleAssembly(assembly, file)); if ((Flags & StartupFlags.Silent) == 0) { Console.WriteLine("Discovered module: " + file); } } } } foreach (var startupAssembly in IntegratedModules) { IntegrateModule(startupAssembly); } PersistentValueSerializer.AddGlobalSerializer(new BitArraySerializer()); InitializeCommandProcessor(); GlobalRules.FinalizeNewRules(); Core.Database = Database; Database.Initialize(); GlobalRules.ConsiderPerformRule("at startup"); if ((Flags & StartupFlags.SingleThreaded) == 0) { StartThreadedCommandProcesor(); } } catch (Exception e) { LogError("Failed to start mud engine."); LogError(e.Message); LogError(e.StackTrace); throw; } return(true); }
// Any function with this signature will be called when the module is loaded. This is our chance to // do anything we want, but usually all we'll do is define some rules. We used some rulebooks above, // now we have to actually define them. public static void AtStartup(RMUD.RuleEngine GlobalRules) { // Lets start by defining some messages we'll use later. This commentary isn't about the message // formatting system, but lets still do this 'right'. Core.StandardMessage("can't push direction", "That isn't going to work."); Core.StandardMessage("you push", "You push <the0> <s1>."); Core.StandardMessage("they push", "^<the0> pushed <the1> <s2>."); Core.StandardMessage("they arrive pushing", "^<the0> arrives <s2> pushing <the1>."); // We'll declare the 'can push direction?' rulebook first. Notice that we were passed the global rules, // and that is what we want to declare it on. DeclareCheckRuleBook takes the types the rulebook // expects as generic arguments, then the name of the rulebook. The documentation is helpful but // not required. This rulebook takes three mud objects. Their usage is documented in the rulebook // description. GlobalRules.DeclareCheckRuleBook <MudObject, MudObject, MudObject>("can push direction?", "[Actor, Subject, Link] : Can the actor push the subject through that link?", "actor", "subject", "link"); // Now we want to define a global rule in the 'can push direction?' rulebook. Rulebooks do not have // to be declared before rules are defined, but it's good style. The Check function returns a // rulebuilder, which provides a fluent interface for declaring rules. GlobalRules.Check <MudObject, MudObject, MudObject>("can push direction?") // Do expects a lambda, and lets us specify what the rule should actually do. .Do((actor, subject, link) => { Core.SendMessage(actor, "@can't push direction"); // We defined this message above. return(CheckResult.Disallow); // Disallow the action. }).Name("Can't push between rooms by default rule."); // So by default, nothing can be pushed between rooms. What a useful command! // That's the only check rule we need. Now lets define the perform rules. We need to duplicate // large portions of the functionality of the go command. I'll comment in a little less detail // now - I think you've got the idea of how this works. These rules will be invoked by the command // in the order they are declared. We could smush them all into one rule, but that would be // poor style maybe. GlobalRules.DeclarePerformRuleBook <MudObject, MudObject, MudObject>("push direction", "[Actor, Subject, Link] : Handle the actor pushing the subject through the link.", "actor", "subject", "link"); // First we want to report the action to the player and any other players that happen to be around. GlobalRules.Perform <MudObject, MudObject, MudObject>("push direction") .Do((actor, subject, link) => { var direction = link.GetProperty <Direction>("link direction"); Core.SendMessage(actor, "@you push", subject, direction.ToString().ToLower()); // SendExternalMessage sends the message to everyone in the same place as the actor, // except the actor themself. Core.SendExternalMessage(actor, "@they push", actor, subject, direction.ToString().ToLower()); return(PerformResult.Continue); }) .Name("Report pushing between rooms rule."); // Now we want to actually move the player, and the object they are pushing. GlobalRules.Perform <MudObject, MudObject, MudObject>("push direction") .Do((actor, subject, link) => { var destination = Core.GetObject(link.GetProperty <String>("link destination")); if (destination == null) { Core.SendMessage(actor, "@bad link"); return(PerformResult.Stop); } Core.Move(actor, destination); Core.Move(subject, destination); return(PerformResult.Continue); }) .Name("Push through the link rule."); // For most actions that's enough. But in this case, we want to let players in the room the // actor went to know they have arrived. GlobalRules.Perform <MudObject, MudObject, MudObject>("push direction") .Do((actor, subject, link) => { var direction = link.GetProperty <Direction>("link direction"); var arriveMessage = Link.FromMessage(Link.Opposite(direction)); Core.SendExternalMessage(actor, "@they arrive pushing", actor, subject, arriveMessage); return(PerformResult.Continue); }) .Name("Report arrival while pushing rule."); // And finally, lets make sure the player gets a description of the room they have arrived in. GlobalRules.Perform <MudObject, MudObject, MudObject>("push direction") .Do((actor, subject, link) => { // We set the 'auto' flag to let the look command know it's been generated, and not // typed by the player. This is handy for deciding wether to show a brief description // or the full description of a room. Core.EnqueuActorCommand(actor, "look", HelperExtensions.MakeDictionary("AUTO", true)); return(PerformResult.Continue); }) .Name("Players look after pushing between rooms rule."); }
public static void AtStartup(RuleEngine GlobalRules) { GlobalRules.DeclarePerformRuleBook <MudObject>("heartbeat", "[Object] : Considered every tick.", "Object"); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { GlobalRules.DeclareValueRuleBook <MudObject, bool>("silly?", "[Thing -> bool] : Determine if an object is silly.", "item"); GlobalRules.Value <MudObject, bool>("silly?").Last.Do((thing) => false).Name("Things are serious by default rule."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can silly?", "[Actor, Target] : Can the actor make the target silly?", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can silly?").First .When((actor, target) => !(target.GetProperty <bool>("actor?"))) .Do((actor, target) => { Core.SendMessage(actor, "That just sounds silly."); return(CheckResult.Disallow); }) .Name("Can only silly actors rule."); GlobalRules.Check <MudObject, MudObject>("can silly?") .Do((actor, target) => Core.CheckIsVisibleTo(actor, target)) .Name("Silly target must be visible."); GlobalRules.Check <MudObject, MudObject>("can silly?") .When((actor, target) => GlobalRules.ConsiderValueRule <bool>("silly?", target)) .Do((actor, target) => { Core.SendMessage(actor, "^<the0> is already silly.", target); return(CheckResult.Disallow); }) .Name("Can't silly if already silly rule."); GlobalRules.Check <MudObject, MudObject>("can silly?") .Last .Do((actor, target) => CheckResult.Allow) .Name("Let the silliness ensue rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("silly", "[Actor, Target] : Apply silly status to the target.", "actor", "item"); GlobalRules.Perform <MudObject, MudObject>("silly") .Do((actor, target) => { Core.SendExternalMessage(actor, "^<the0> applies extra silly to <the1>.", actor, target); Core.SendMessage(actor, "You apply extra silly to <the0>.", target); var ruleID = Guid.NewGuid(); var counter = 100; target.AddNoun("silly"); target.Value <MudObject, bool>("silly?").Do((thing) => true).ID(ruleID.ToString()) .Name("Silly things are silly rule."); target.Value <MudObject, MudObject, String, String>("printed name") .Do((viewer, thing, article) => { return("silly " + thing.GetProperty <String>("short")); }) .Name("Silly things have silly names rule.") .ID(ruleID.ToString()); GlobalRules.Perform("heartbeat") .Do(() => { counter -= 1; if (counter <= 0) { Core.SendExternalMessage(target, "^<the0> is serious now.", target); target.GetProperty <NounList>("nouns").Remove("silly"); target.Rules.DeleteAll(ruleID.ToString()); GlobalRules.DeleteRule("heartbeat", ruleID.ToString()); } return(PerformResult.Continue); }) .ID(ruleID.ToString()) .Name("Countdown to seriousness rule."); return(PerformResult.Continue); }) .Name("Apply sillyness rule."); GlobalRules.DeclareCheckRuleBook <MudObject>("can dance?", "[Actor] : Can the actor dance?", "actor"); GlobalRules.Check <MudObject>("can dance?") .When(actor => !GlobalRules.ConsiderValueRule <bool>("silly?", actor)) .Do(actor => { Core.SendMessage(actor, "You don't feel silly enough for that."); return(CheckResult.Disallow); }) .Name("Your friends don't dance rule."); GlobalRules.Check <MudObject>("can dance?") .Last .Do(actor => CheckResult.Allow) .Name("You can dance if you want to rule."); GlobalRules.DeclarePerformRuleBook <MudObject>("dance", "[Actor] : Perform a silly dance.", "actor"); GlobalRules.Perform <MudObject>("dance") .Do(actor => { Core.SendExternalMessage(actor, "^<the0> does a very silly dance.", actor); Core.SendMessage(actor, "You do a very silly dance."); return(PerformResult.Continue); }) .Name("They aren't no friends of mine rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { PropertyManifest.RegisterProperty("interlocutor", typeof(MudObject), null, new DefaultSerializer()); PropertyManifest.RegisterProperty("conversation-topics", typeof(List <MudObject>), new List <MudObject>(), new DefaultSerializer()); PropertyManifest.RegisterProperty("topic-discussed", typeof(bool), false, new BoolSerializer()); Core.StandardMessage("convo topic prompt", "Suggested topics: <l0>"); Core.StandardMessage("convo cant converse", "You can't converse with that."); Core.StandardMessage("convo greet whom", "Whom did you want to greet?"); Core.StandardMessage("convo nobody", "You aren't talking to anybody."); Core.StandardMessage("convo no response", "There doesn't seem to be a response defined for that topic."); Core.StandardMessage("convo no topics", "There is nothing obvious to discuss."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can converse?", "[Actor, Item] : Can the actor converse with the item?", "actor", "item"); GlobalRules.Check <MudObject, MudObject>("can converse?") .When((actor, item) => !item.GetProperty <bool>("actor?")) .Do((actor, item) => { Core.SendMessage(actor, "@convo cant converse"); return(CheckResult.Disallow); }) .Name("Can only converse with NPCs rule."); GlobalRules.Check <MudObject, MudObject>("can converse?") .Do((actor, item) => Core.CheckIsVisibleTo(actor, item)) .Name("Locutor must be visible rule."); GlobalRules.Check <MudObject, MudObject>("can converse?") .Last .Do((actor, item) => CheckResult.Allow) .Name("Let them chat rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("greet", "[Actor, NPC] : Handle an actor greeting an NPC.", "actor", "npc"); GlobalRules.DeclarePerformRuleBook <MudObject>("list topics", "[Actor] : List conversation topics available to the actor.", "actor"); GlobalRules.Perform <MudObject>("list topics") .When(actor => actor.GetProperty <MudObject>("interlocutor") == null) .Do(actor => { Core.SendMessage(actor, "@convo nobody"); return(PerformResult.Stop); }) .Name("Need interlocutor to list topics rule."); GlobalRules.Perform <MudObject>("list topics") .Do(actor => { var npc = actor.GetProperty <MudObject>("interlocutor"); if (npc != null) { var suggestedTopics = npc.GetProperty <List <MudObject> >("conversation-topics").AsEnumerable(); if (!ConversationSettings.ListDiscussedTopics) { suggestedTopics = suggestedTopics.Where(obj => !obj.GetProperty <bool>("topic-discussed")); } suggestedTopics = suggestedTopics.Where(topic => GlobalRules.ConsiderCheckRule("topic available?", actor, npc, topic) == CheckResult.Allow); var enumeratedSuggestedTopics = new List <MudObject>(suggestedTopics); if (enumeratedSuggestedTopics.Count != 0) { Core.SendMessage(actor, "@convo topic prompt", enumeratedSuggestedTopics); } else { GlobalRules.ConsiderPerformRule("no topics to discuss", actor, npc); } } return(PerformResult.Continue); }) .Name("List un-discussed available topics rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("no topics to discuss", "[Actor, NPC] : Handle there being no topics to list."); GlobalRules.Perform <MudObject, MudObject>("no topics to discuss") .Do((actor, npc) => { Core.SendMessage(actor, "@convo no topics"); return(PerformResult.Continue); }) .Name("Default report no topics to discuss rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject, MudObject>("discuss topic", "[Actor, NPC, Topic] : Handle the actor discussing the topic with the npc."); GlobalRules.Perform <MudObject, MudObject, MudObject>("discuss topic") .Do((actor, npc, topic) => { GlobalRules.ConsiderPerformRule("topic response", actor, npc, topic); if (topic != null) { topic.SetProperty("topic-discussed", true); } return(PerformResult.Continue); }) .Name("Show topic response when discussing topic rule."); GlobalRules.Perform <MudObject, MudObject, MudObject>("topic response") .Do((actor, npc, topic) => { Core.SendMessage(actor, "@convo no response"); return(PerformResult.Stop); }) .Name("No response rule for the topic rule."); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject, MudObject>("topic available?", "[Actor, NPC, Topic -> bool] : Is the topic available for discussion with the NPC to the actor?", "actor", "npc", "topic"); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject, MudObject>("topic response", "[Actor, NPC, Topic] : Display the response of the topic.", "actor", "npc", "topic"); GlobalRules.Check <MudObject, MudObject, MudObject>("topic available?") .First .When((actor, npc, topic) => (topic != null) && (ConversationSettings.AllowRepeats == false) && topic.GetProperty <bool>("topic-discussed")) .Do((actor, npc, topic) => CheckResult.Disallow) .Name("Already discussed topics unavailable when repeats disabled rule."); GlobalRules.Check <MudObject, MudObject, MudObject>("topic available?") .Last .Do((actor, npc, topic) => CheckResult.Allow) .Name("Topics available by default rule."); }
public static void AtStartup(RMUD.RuleEngine GlobalRules) { PropertyManifest.RegisterProperty("introduction memory", typeof(Dictionary <String, bool>), null, new DefaultSerializer()); GlobalRules.DeclareCheckRuleBook <MudObject, MudObject>("can introduce?", "[Actor A, Actor B] : Can A introduce B?", "actor", "itroductee"); GlobalRules.Check <MudObject, MudObject>("can introduce?") .When((a, b) => !b.GetProperty <bool>("actor?")) .Do((a, b) => { Core.SendMessage(a, "That just sounds silly."); return(CheckResult.Disallow); }) .Name("Can only introduce actors rule."); GlobalRules.Check <MudObject, MudObject>("can introduce?") .Do((a, b) => Core.CheckIsVisibleTo(a, b)) .Name("Introducee must be visible rule."); GlobalRules.Check <MudObject, MudObject>("can introduce?") .When((a, b) => !GlobalRules.ConsiderValueRule <bool>("actor knows actor?", a, b)) .Do((a, b) => { Core.SendMessage(a, "How can you introduce <the0> when you don't know them yourself?", b); return(CheckResult.Disallow); }) .Name("Can't introduce who you don't know rule."); GlobalRules.Perform <MudObject, MudObject>("describe") .First .When((viewer, actor) => GlobalRules.ConsiderValueRule <bool>("actor knows actor?", viewer, actor)) .Do((viewer, actor) => { Core.SendMessage(viewer, "^<the0>, a " + (actor.GetProperty <Gender>("gender") == Gender.Male ? "man." : "woman."), actor); return(PerformResult.Continue); }) .Name("Report gender of known actors rule."); #region Perform and report rules GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("introduce", "[Actor A, Actor B] : Handle A introducing B.", "actor", "introductee"); GlobalRules.Perform <MudObject, MudObject>("introduce") .Do((actor, introductee) => { var locale = Core.FindLocale(introductee); if (locale != null) { foreach (var player in Core.EnumerateObjectTree(locale).Where(o => o.GetProperty <bool>("actor?"))) { GlobalRules.ConsiderPerformRule("introduce to", introductee, player); } } Core.SendExternalMessage(actor, "^<the0> introduces <the1>.", actor, introductee); Core.SendMessage(actor, "You introduce <the0>.", introductee); return(PerformResult.Continue); }) .Name("Report introduction rule."); GlobalRules.DeclarePerformRuleBook <MudObject>("introduce self", "[Introductee] : Introduce the introductee"); GlobalRules.Perform <MudObject>("introduce self") .Do((introductee) => { var locale = Core.FindLocale(introductee); if (locale != null) { foreach (var player in Core.EnumerateObjectTree(locale).Where(o => o.GetProperty <bool>("actor?"))) { GlobalRules.ConsiderPerformRule("introduce to", introductee, player); } } Core.SendExternalMessage(introductee, "^<the0> introduces themselves.", introductee); Core.SendMessage(introductee, "You introduce yourself."); return(PerformResult.Continue); }) .Name("Introduce an actor to everyone present rule."); #endregion #region Printed name rules GlobalRules.Value <MudObject, MudObject, String, String>("printed name") .When((viewer, thing, article) => thing.GetProperty <bool>("actor?")) .When((viewer, thing, article) => GlobalRules.ConsiderValueRule <bool>("actor knows actor?", viewer, thing)) .Do((viewer, actor, article) => actor.GetProperty <String>("short")) .Name("Name of introduced actor."); GlobalRules.Value <MudObject, MudObject, String, String>("printed name") .When((viewer, thing, article) => thing.GetProperty <bool>("actor?")) .When((viewer, thing, article) => thing.GetProperty <Gender>("gender") == Gender.Male) .Do((viewer, actor, article) => article + " man") .Name("Default name for unintroduced male actor."); GlobalRules.Value <MudObject, MudObject, String, String>("printed name") .When((viewer, thing, article) => thing.GetProperty <bool>("actor?")) .When((viewer, thing, article) => thing.GetProperty <Gender>("gender") == Gender.Female) .Do((viewer, actor, article) => article + " woman") .Name("Default name for unintroduced female actor."); #endregion #region Knowledge management rules GlobalRules.DeclareValueRuleBook <MudObject, MudObject, bool>("actor knows actor?", "[Player, Whom] : Does the player know the actor?"); GlobalRules.Value <MudObject, MudObject, bool>("actor knows actor?") .Do((player, whom) => RecallActor(player, whom)) .Name("Use player memory to recall actors rule."); GlobalRules.DeclarePerformRuleBook <MudObject, MudObject>("introduce to", "[Introductee, ToWhom] : Introduce the introductee to someone"); GlobalRules.Perform <MudObject, MudObject>("introduce to") .Do((introductee, player) => { RememberActor(player, introductee); return(PerformResult.Continue); }) .Name("Players remember actors rule."); #endregion }