private void SavePersistentObject(MudObject Object) { var filename = DynamicPath + Object.GetFullName() + ".txt"; Directory.CreateDirectory(System.IO.Path.GetDirectoryName(filename)); var data = Core.SerializeObject(Object); System.IO.File.WriteAllText(filename, data); }
/// <summary> /// Determine if an object is contained by another. /// Note that nothing prevents an object containing itself, however, this function will report /// false for any loop in the containment graph. /// </summary> /// <param name="Super">Reference point object</param> /// <param name="Sub">Object to be tested</param> /// <returns></returns> public static bool ObjectContainsObject(MudObject Super, MudObject Sub) { if (Object.ReferenceEquals(Super, Sub)) return false; //Objects can't contain themselves... if (Sub.Location == null) return false; if (Object.ReferenceEquals(Super, Sub.Location)) return true; return ObjectContainsObject(Super, Sub.Location); }
private void ReadPersistentObject(MudObject Object) { var filename = DynamicPath + Object.GetFullName() + ".txt"; if (!System.IO.File.Exists(filename)) return; var data = System.IO.File.ReadAllText(filename); Core.DeserializeObject(Object, data); }
private static IEnumerable<Tuple<System.Reflection.PropertyInfo, PersistAttribute>> EnumeratePersistentProperties(MudObject Object) { return Object.GetType().GetProperties() .Where(pi => pi.GetCustomAttributes(true).Count(a => a is PersistAttribute) >= 1) .Select(pi => Tuple.Create(pi, pi.GetCustomAttributes(true).FirstOrDefault(a => a is PersistAttribute) as PersistAttribute)); }
public override void ForgetInstance(MudObject Object) { var instanceName = Object.Path + "@" + Object.Instance; if (ActiveInstances.ContainsKey(instanceName)) ActiveInstances.Remove(instanceName); Object.IsPersistent = false; }
public static Object _ReadValue(Type ValueType, JsonReader Reader, MudObject Owner) { Object r = null; if (Reader.TokenType == JsonToken.String) { r = Reader.Value.ToString(); Reader.Read(); } else if (Reader.TokenType == JsonToken.Integer) { r = Convert.ToInt32(Reader.Value.ToString()); Reader.Read(); } else if (Reader.TokenType == JsonToken.Boolean) { r = Convert.ToBoolean(Reader.Value.ToString()); Reader.Read(); } else { PersistentValueSerializer serializer = null; if (ValueType != null && PersistentValueSerializer.GlobalSerializers.TryGetValue(ValueType.Name, out serializer)) return serializer.ReadValue(ValueType, Reader, Owner); else if (Reader.TokenType == JsonToken.StartObject) { Reader.Read(); if (Reader.TokenType != JsonToken.PropertyName || Reader.Value.ToString() != "$type") throw new InvalidOperationException(); Reader.Read(); if (!PersistentValueSerializer.GlobalSerializers.TryGetValue(Reader.Value.ToString(), out serializer)) throw new InvalidOperationException(); Reader.Read(); Reader.Read(); r = serializer.ReadValue(ValueType, Reader, Owner); Reader.Read(); } else throw new InvalidOperationException(); } return r; }
public override object ReadValue(Type ValueType, Newtonsoft.Json.JsonReader Reader, MudObject Owner) { var r = new Dictionary<RelativeLocations, List<MudObject>>(); Reader.Read(); while (Reader.TokenType != Newtonsoft.Json.JsonToken.EndObject) { var relloc = StringToRelativeLocation(Reader.Value.ToString()); var l = new List<MudObject>(); Reader.Read(); Reader.Read(); while (Reader.TokenType != Newtonsoft.Json.JsonToken.EndArray) { var mudObject = MudObject.GetObject(Reader.Value.ToString()); if (mudObject != null) l.Add(mudObject); mudObject.Location = Owner; Reader.Read(); } Reader.Read(); r.Upsert(relloc, l); } Reader.Read(); return r; }
public static void SendExternalMessage(MudObject Actor, String Message, params Object[] MentionedObjects) { if (String.IsNullOrEmpty(Message)) return; if (Core.SilentFlag) return; Core.OutputQueryTriggered = true; SendExternalMessage(Actor as Actor, Message, MentionedObjects); }
/// <summary> /// Encapsulates the containment relation for easy use by check rules. /// Note that this relation is stricter than the VisibleTo relation. /// </summary> /// <param name="Actor">Reference point object</param> /// <param name="Item">Object to be tested</param> /// <returns></returns> public static CheckResult CheckIsHolding(MudObject Actor, MudObject Item) { if (!MudObject.ObjectContainsObject(Actor, Item)) { MudObject.SendMessage(Actor, "@dont have that"); return CheckResult.Disallow; } return CheckResult.Continue; }
/// <summary> /// Encapsulates the VisibleTo relation for easy use by check rules. /// </summary> /// <param name="Actor">Reference point object</param> /// <param name="Item">Object to be tested</param> /// <returns></returns> public static CheckResult CheckIsVisibleTo(MudObject Actor, MudObject Item) { if (!MudObject.IsVisibleTo(Actor, Item)) { MudObject.SendMessage(Actor, "@gone"); return CheckResult.Disallow; } return CheckResult.Continue; }
private void OnTopicDiscussed(MudObject Player) { TopicsDiscussed += 1; if (TopicsDiscussed == 2) { SendMessage(Player, "Where are you Sal?"); ConversationPhase = 1; } }
/// <summary> /// Determine is an object is visible to another object. This is essentially a comparison of the /// locale of the two objects. However, some special cases must be accounted for. /// a) A closed container is visible to it's contents, despite having different locales, /// and the reverse. /// </summary> /// <param name="Actor">The reference point object</param> /// <param name="Object">The object to be tested</param> /// <returns>True if the reference point object can 'see' the tested object, false otherwise.</returns> public static bool IsVisibleTo(MudObject Actor, MudObject Object) { var actorLocale = MudObject.FindLocale(Actor); if (actorLocale == null) return false; var objectLocale = MudObject.FindLocale(Object); return System.Object.ReferenceEquals(actorLocale, objectLocale) || System.Object.ReferenceEquals(actorLocale, Object) || System.Object.ReferenceEquals(objectLocale, Actor); }
private void AutoClose(MudObject Player, Hatch Hatch) { if (Hatch.GetBooleanProperty("open?")) { Hatch.SetProperty("open?", false); var otherSide = Portal.FindOppositeSide(Hatch); if (otherSide != null) otherSide.SetProperty("open?", false); MudObject.SendMessage(Player, "^<the0> closes.", Hatch); } }
public MudObject AddScenery(String Description, params String[] Nouns) { var scenery = new MudObject(); scenery.SetProperty("scenery?", true); scenery.Long = Description; foreach (var noun in Nouns) scenery.Nouns.Add(noun.ToUpper()); AddScenery(scenery); return scenery; }
public String Expand(Actor Viewer, MudObject Source) { switch (TextType) { case DescriptiveTextType.LambdaText: return LambdaText(Viewer, Source); case DescriptiveTextType.TaggedText: return RawText; } return null; }
public static void SendLocaleMessage(MudObject Object, String Message, params Object[] MentionedObjects) { if (String.IsNullOrEmpty(Message)) return; if (Core.SilentFlag) return; Core.OutputQueryTriggered = true; var container = MudObject.FindLocale(Object) as Container; if (container != null) foreach (var actor in container.EnumerateObjects<Actor>().Where(a => a.ConnectedClient != null)) Core.PendingMessages.Add(new PendingMessage(actor.ConnectedClient, Core.FormatMessage(actor, Message, MentionedObjects))); }
public static void OfferQuest(this MudObject This, Actor Actor, MudObject Quest) { var player = Actor as Player; if (player != null) { MudObject.SendMessage(Actor, "[To accept this quest, enter the command 'accept quest'.]"); if (player.GetProperty<MudObject>("active-quest") != null) MudObject.SendMessage(Actor, "[Accepting this quest will abandon your active quest.]"); player.SetProperty("offered-quest", Quest); } }
private static IEnumerable<MudObject> _enumerateObjectTree(MudObject C) { if (C != null) { yield return C; if (C is Container) foreach (var item in (C as Container).EnumerateObjects()) foreach (var sub in _enumerateObjectTree(item)) yield return sub; } }
/// <summary> /// Given a portal, find the opposite side. Portals are used to connect two rooms. The opposite side of /// the portal is assumed to be the portal in the linked room that faces the opposite direction. For example, /// if portal A is in room 1, faces west, and is linked to room 2, the opposite side would be the portal /// in room 2 that faces east. It does not actually check to see if the opposite side it finds is linked /// to the correct room. /// </summary> /// <param name="Portal"></param> /// <returns></returns> public static MudObject FindOppositeSide(MudObject Portal) { // Every object added to a room as a portal will be given the 'portal?' property, with a value of true. if (Portal.GetPropertyOrDefault<bool>("portal?", false) == false) return null; // Not a portal. var destination = MudObject.GetObject(Portal.GetProperty<String>("link destination")) as Room; if (destination == null) return null; // Link is malformed in some way. var direction = Portal.GetPropertyOrDefault<Direction>("link direction", Direction.NOWHERE); var oppositeDirection = Link.Opposite(direction); var mirrorLink = destination.EnumerateObjects().FirstOrDefault(p => p.GetBooleanProperty("portal?") && p.GetPropertyOrDefault<Direction>("link direction", Direction.NOWHERE) == oppositeDirection); return mirrorLink; }
/// <summary> /// Flatten and serialize a MudObject into a string. /// </summary> /// <param name="Object"></param> /// <returns></returns> internal static String SerializeObject(MudObject Object) { var dest = new System.IO.StringWriter(); var jsonWriter = new JsonTextWriter(dest); jsonWriter.WriteStartObject(); foreach (var property in EnumeratePersistentProperties(Object)) { jsonWriter.WritePropertyName(property.Item1.Name); property.Item2.WriteValue(property.Item1.GetValue(Object, null), jsonWriter, Object); } jsonWriter.WriteEndObject(); return dest.ToString(); }
/// <summary> /// Move Object to Destination. /// </summary> /// <param name="Object">Object to move.</param> /// <param name="Destination">Destination to move too.</param> /// <param name="Location">The relative location within destination to move too.</param> public static void Move(MudObject Object, MudObject Destination, RelativeLocations Location = RelativeLocations.Default) { if (Object == null) return; if (Object.Location != null && Object.Location is Container) (Object.Location as Container).Remove(Object); if (Destination is Container) { (Destination as Container).Add(Object, Location); Object.Location = Destination; } else Object.Location = null; }
public override void PersistInstance(MudObject Object) { if (Object.IsPersistent) return; //The object is already persistent. if (ActiveInstances.ContainsKey(Object.GetFullName())) throw new InvalidOperationException("An instance with this name is already persisted."); if (Object.IsNamedObject) { Object.IsPersistent = true; ActiveInstances.Upsert(Object.GetFullName(), Object); ReadPersistentObject(Object); } else throw new InvalidOperationException("Anonymous objects cannot be persisted."); }
public override void WriteValue(object Value, Newtonsoft.Json.JsonWriter Writer, MudObject Owner) { var contents = Value as Dictionary<String, Object>; if (contents == null) throw new InvalidOperationException(); Writer.WriteStartObject(); foreach (var pair in contents) { Writer.WritePropertyName(pair.Key); PersistAttribute._WriteValue(pair.Value, Writer, Owner); } Writer.WriteEndObject(); }
public static void _WriteValue(Object Value, JsonWriter Writer, MudObject Owner) { var name = Value.GetType().Name; PersistentValueSerializer serializer = null; if (PersistentValueSerializer.GlobalSerializers.TryGetValue(name, out serializer)) { Writer.WriteStartObject(); Writer.WritePropertyName("$type"); Writer.WriteValue(name); Writer.WritePropertyName("$value"); serializer.WriteValue(Value, Writer, Owner); Writer.WriteEndObject(); } else Writer.WriteValue(Value); //Hope... }
private static IEnumerable<MudObject> _enumerateVisibleTree(MudObject C) { if (C != null) { yield return C; if (C is Container) foreach (var list in (C as Container).Lists) { if (list.Key == RelativeLocations.In && C.GetBooleanProperty("openable?") && !C.GetBooleanProperty("open?")) continue; foreach (var item in list.Value) foreach (var sub in _enumerateVisibleTree(item)) yield return sub; } } }
public override object ReadValue(Type ValueType, Newtonsoft.Json.JsonReader Reader, MudObject Owner) { var r = new Dictionary<String, Object>(); Reader.Read(); while (Reader.TokenType != Newtonsoft.Json.JsonToken.EndObject) { var name = Reader.Value.ToString(); Reader.Read(); var value = PersistAttribute._ReadValue(null, Reader, Owner); r.Upsert(name, value); } Reader.Read(); return r; }
public static void Move(Thing Thing, MudObject Destination) { if (Thing.Location != null) { var container = Thing.Location as IContainer; if (container != null) container.Remove(Thing); Thing.Location = null; } if (Destination != null) { var destinationContainer = Destination as IContainer; if (destinationContainer != null) destinationContainer.Add(Thing); Thing.Location = Destination; } }
public void OpenLink(Direction Direction, String Destination, MudObject Portal = null) { if (RemoveAll(thing => thing.GetPropertyOrDefault<Direction>("link direction", RMUD.Direction.NOWHERE) == Direction && thing.GetPropertyOrDefault<bool>("portal?", false)) > 0) Core.LogWarning("Opened duplicate link in " + Path); if (Portal == null) { Portal = new MudObject(); Portal.SetProperty("link anonymous?", true); Portal.Short = "link " + Direction + " to " + Destination; } Portal.SetProperty("portal?", true); Portal.SetProperty("link direction", Direction); Portal.SetProperty("link destination", Destination); Portal.Location = this; Add(Portal, RelativeLocations.Contents); }
/// <summary> /// Find the locale of an object. The locale is the top level room that encloses the object. /// For example, if the object is in an open box, on a table, in a room, the room is the locale. /// Closed containers are considered the top level object, so if an object is in a closed box, /// on a table, in a room, the box is the locale. /// </summary> /// <param name="Of">The object to find the locale of.</param> /// <returns>The locale of the object.</returns> public static MudObject FindLocale(MudObject Of) { if (Of == null || Of.Location == null) return Of; //If the object is in a container, check to see if that container is open. var container = Of.Location as Container; if (container != null) { if (container.RelativeLocationOf(Of) == RelativeLocations.In) { if (Of.Location.GetPropertyOrDefault<bool>("open?", false)) return FindLocale(Of.Location); else return Of.Location; } } return FindLocale(Of.Location); }
public override void WriteValue(object Value, Newtonsoft.Json.JsonWriter Writer, MudObject Owner) { var contents = Value as Dictionary<RelativeLocations, List<MudObject>>; if (contents == null) throw new InvalidOperationException(); Writer.WriteStartObject(); foreach (var relloc in contents) { Writer.WritePropertyName(RelativeLocationToString(relloc.Key)); Writer.WriteStartArray(); foreach (var mudObject in relloc.Value.Where(o => o.IsNamedObject && o.IsInstance)) Writer.WriteValue(mudObject.GetFullName()); Writer.WriteEndArray(); } Writer.WriteEndObject(); }