// ************************************************** // * ____ _ _ _ _ _ _ ___ * // * | _ \ ___| |__ (_)_ __| |_| |__ | | | |/ _ \ * // * | |_) / _ \ '_ \| | '__| __| '_ \| | | | | | | * // * | _ < __/ |_) | | | | |_| | | | |_| | |_| | * // * |_| \_\___|_.__/|_|_| \__|_| |_|\___/ \___/ * // ************************************************** // * File : UOEntity.cs // * Created : 22 06 2015 // * Updated : 22 06 2015 // * Website : www.RebirthUO.com // ************************************************** using System; using System.Collections.Generic; using System.Linq; using ScriptDotNet2; using ScriptDotNet2.Data; namespace ScriptSDK { public enum UOEntityData { Serial, Parent, RootParent, ObjectValidation, Map, Distance, ToolTip, ToolTipParsingDelay, Direction, Layer, Location, Properties, ContextMenu, Hue, ObjectType } public enum Map : byte { Felucca = 0, Trammel = 1, Ilshenar = 2, Malas = 3, Tokuno = 4, TerMur = 5, #region RebirthUO EventFelucca = 33, EventTrammel = 34, EventIlshenar = 35, EventMalas = 36, EventTokuno = 37, EventTerMur = 38, #endregion Internal = 0x7F } public enum Direction : byte { North = 0x0, Right = 0x1, East = 0x2, Down = 0x3, South = 0x4, Left = 0x5, West = 0x6, Up = 0x7 } public class UOEntity : Entity { public UOEntity(uint value) { Initialize(); RegisterData(UOEntityData.Serial, new Serial(value)); } public UOEntity(Serial serial) : this(serial != null ? serial.Value : 0) { } public int ToolTipParserDelay { get { return GetValue(UOEntityData.ToolTipParsingDelay); } set { SetValue(UOEntityData.ToolTipParsingDelay, value); } } public virtual string Tooltip { get { return GetValue(UOEntityData.ToolTip); } } public Serial Serial { get { return GetValue(UOEntityData.Serial); } set { SetValue(UOEntityData.Serial, value); Initialize(); } } public virtual Layer Layer { get { return GetValue(UOEntityData.Layer); } } public virtual UOEntity Parent { get { return GetValue(UOEntityData.Parent); } } public virtual UOEntity RootParent { get { return GetValue(UOEntityData.RootParent); } } public virtual Point3D Location { get { return GetValue(UOEntityData.Location); } } public virtual Map Map { get { return GetValue(UOEntityData.Map); } } public virtual bool Valid { get { return GetValue(UOEntityData.ObjectValidation); } } public virtual Direction Direction { get { return GetValue(UOEntityData.Direction); } } public virtual ContextMenu ContextMenu { get { return GetValue(UOEntityData.ContextMenu); } } public virtual ushort Color { get { return GetValue(UOEntityData.Hue); } } public virtual ushort ObjectType { get { return GetValue(UOEntityData.ObjectType); } } public virtual int Distance { get { return GetValue(UOEntityData.Distance); } } public virtual List Properties { get { return GetValue>(UOEntityData.Properties); } } protected override bool CanReadBaseValue(Enum key) { if (key is UOEntityData) { var k = (UOEntityData) key; if (k.Equals(UOEntityData.ToolTipParsingDelay)) return false; if (k.Equals(UOEntityData.Serial)) return false; } return base.CanReadBaseValue(key); } protected override object GetBaseValue(Enum key) { if (key is UOEntityData) { var k = (UOEntityData) key; switch (k) { case UOEntityData.ToolTip: { return Stealth.Default.GetTooltip(Serial.Value); } case UOEntityData.ObjectValidation: { return Stealth.Default.IsObjectExists(Serial.Value); } case UOEntityData.Map: { if (!GetValue(UOEntityData.ObjectValidation)) return Map.Internal; var b = Stealth.Default.GetWorldNum(); var l = Enum.GetValues(typeof (Map)) as byte[]; if (l == null) return Map.Internal; if (l.Contains(b)) return (Map) b; return Map.Internal; } case UOEntityData.Distance: { return Stealth.Default.GetDistance(Serial.Value); } case UOEntityData.Direction: { return (Direction) Stealth.Default.GetDirection(Serial.Value); } case UOEntityData.Layer: { var b = Stealth.Default.GetLayer(Serial.Value); var l = Enum.GetValues(typeof (Layer)) as byte[]; if (l == null) return Layer.Invalid; if (l.Contains(b)) return (Layer) b; return Layer.Invalid; } case UOEntityData.Location: { return new Point3D(Stealth.Default.GetX(Serial.Value), Stealth.Default.GetY(Serial.Value), Stealth.Default.GetZ(Serial.Value)); } case UOEntityData.Parent: { return new UOEntity(Stealth.Default.GetParent(Serial.Value)); //GenerateVersion(Config.Options.Version,new Serial(Stealth.Default.GetParent(Serial.Value)));//TODO : Coming Soon } case UOEntityData.RootParent: { var p = Parent; while (!p.Serial.Value.Equals(0)) { var item = p; if (item.Parent.Serial.Value.Equals(0)) { p = item; break; } p = item.Parent; } return p; //GenerateVersion(Config.Options.Version,new Serial(Stealth.Default.GetParent(Serial.Value))); //TODO : Coming Soon } case UOEntityData.Properties: { return Stealth.Default.GetClilocRec(Serial.Value); } case UOEntityData.ContextMenu: { ((ContextMenu) _datatable[key]).Update(); return _datatable[key]; } case UOEntityData.ObjectType: { return Stealth.Default.GetType(Serial.Value); } case UOEntityData.Hue: { return Stealth.Default.GetColor(Serial.Value); } } } return base.GetBaseValue(key); } protected override void Initialize() { base.Initialize(); RegisterData(UOEntityData.ToolTip, ""); RegisterData(UOEntityData.ToolTipParsingDelay, 200); RegisterData(UOEntityData.ObjectValidation, false); RegisterData(UOEntityData.Map, Map.Internal); RegisterData(UOEntityData.Distance, 0); RegisterData(UOEntityData.Direction, Direction.Down); RegisterData(UOEntityData.Layer, Layer.Invalid); RegisterData(UOEntityData.Location, new Point3D(0, 0, 0)); RegisterData(UOEntityData.Parent, 0); RegisterData(UOEntityData.RootParent, 0); RegisterData(UOEntityData.Properties, new List()); RegisterData(UOEntityData.ObjectType, 0); RegisterData(UOEntityData.Hue, 0); RegisterData(UOEntityData.ContextMenu, new ContextMenu(this)); } public static UOEntity GenerateVersion(Version version, Serial serial) { if (serial.Value > 0 && serial.Value < 0x40000000) return new UOEntity(serial); //TODO cast return Item.GenerateVersion(version, serial); if (serial.Value >= 0x40000000 && serial.Value <= 0x7FFFFFFF) return new UOEntity(serial); //TODO cast Mobile.GenerateVersion(serial); return new UOEntity(serial); } public virtual bool Click() { if (!GetValue(UOEntityData.ObjectValidation)) return false; Stealth.Default.ClickOnObject(Serial.Value); return true; } public virtual bool Use() { if (!GetValue(UOEntityData.ObjectValidation)) return false; Stealth.Default.UseObject(Serial.Value); return true; } public override void Update() { if (!EntityMode.Equals(EntityMode.Refresh)) return; _datatable[UOEntityData.Properties] = GetBaseValue(UOEntityData.Properties); base.Update(); } } } // ************************************************** // * ____ _ _ _ _ _ _ ___ * // * | _ \ ___| |__ (_)_ __| |_| |__ | | | |/ _ \ * // * | |_) / _ \ '_ \| | '__| __| '_ \| | | | | | | * // * | _ < __/ |_) | | | | |_| | | | |_| | |_| | * // * |_| \_\___|_.__/|_|_| \__|_| |_|\___/ \___/ * // ************************************************** // * File : Entity.cs // * Created : 22 06 2015 // * Updated : 22 06 2015 // * Website : www.RebirthUO.com // ************************************************** using System; using System.Collections.Generic; using System.Linq; namespace ScriptSDK { public enum EntityData { EntityMode } public enum EntityMode { Store, Refresh } public class Entity { /// /// Root Constructor, if this is not called by inheritence the whole system will have trouble!!! /// public Entity() { _datatable = new Dictionary(); Initialize(); } /// /// Entity Mode decides how the Object will read the properties. /// /// Refresh : /// + Faster when require single informations on fly /// + Always updated informations /// - Slow when calling tons of Cliloc Properties /// - Not suited for a full Checkup if you need properties multiple times /// /// Store : /// + Update() will store all data via API /// + You can reread the stored data anytime (even import\export) /// - Slow because of many API-Calls at once /// - Not suited for Time Critical Handlings /// - Requires the Call of "Update()" in order to get Data /// public EntityMode EntityMode { get { return GetValue(EntityData.EntityMode); } set { SetValue(EntityData.EntityMode, value); } } /// /// Object wich stores data, avoid using this directly /// protected Dictionary _datatable { get; set; } /// /// Initializer of propertys to data map.Except propertys you want for copy data you should move all new propertys here /// protected virtual void Initialize() { RegisterData(EntityData.EntityMode, EntityMode.Refresh); } /// /// Simple way to register a new property. Will fill data with an object dummy /// /// protected void RegisterData(Enum key) { if (_datatable == null) _datatable = new Dictionary(); if (!_datatable.ContainsKey(key)) _datatable.Add(key, new object()); } /// /// Returns the ObjectType as String /// /// public override string ToString() { return GetType().ToString(); } /// /// Method to register a new property together with a value /// /// /// /// protected void RegisterData(Enum key, T value) { RegisterData(key); SetValue(key, value); } /// /// This method provides the API-Calls (or alternative databuilds). When you call Update() or EntityMode is Refresh, /// this method describes where to get the data /// /// /// protected virtual object GetBaseValue(Enum key) { return null; } /// /// Generic Setter Method for datamapping /// /// /// /// protected void SetValue(Enum key, T value) { if (_datatable == null) return; if (_datatable.ContainsKey(key)) _datatable[key] = value; } /// /// This Method allows to ignore the "GetBaseValue" call. Sometimes there are attributes, wich could do trouble /// deadlocks on recursive calls(such as EntityMode) or you just never want to call the api for that. Then you can /// Check the Key and disable the GetBaseValue call. Instead of GetBaseValue it will just do _datatable[key] and returns the stored value. /// /// /// protected virtual bool CanReadBaseValue(Enum key) { return !(key is EntityData); } /// /// The Same Idea as CanReadBaseValue but as reverted. If you have something Cliloc related you can return true and it forwards /// to method GetBaseClilocValue where you can handle forwardly. On Update i integrated a Property Update before calling the Cliloc stuff, /// this reduce the calls of Api for parsing Cliloc-Property data from Properties. /// /// /// protected virtual bool IsClilocData(Enum key) { return false; } /// /// Whenever IsClilocData returns true this method will be called instead of GetBaseValue. Theoreticly it should work the same way as /// GetBaseValue, but it depends on you, how you update cliloc related data with given Properties. /// /// /// protected virtual object GetBaseClilocValue(Enum key) { return null; } /// /// Generic Getter for datamapping, allows to read either /// /// /// /// protected T GetValue(Enum key) { if (!(CanReadBaseValue(key))) return (T)_datatable[key]; if (_datatable == null) return IsClilocData(key) ? (T)GetBaseClilocValue(key) : (T)GetBaseValue(key); if (!_datatable.ContainsKey(key)) RegisterData(key, IsClilocData(key) ? (T)GetBaseClilocValue(key) : (T)GetBaseValue(key)); else if (EntityMode.Equals(EntityMode.Refresh)) _datatable[key] = (IsClilocData(key) ? (T)GetBaseClilocValue(key) : (T)GetBaseValue(key)); return (T)_datatable[key]; } /// /// Update Method for Store-driven EntityMode (Slow but updated all data) /// public virtual void Update() { if (!EntityMode.Equals(EntityMode.Refresh)) return; if (_datatable == null) return; SetValue(EntityData.EntityMode, EntityMode.Refresh); var keys = _datatable.Keys.ToList(); foreach (var k in keys.Where(k => _datatable.ContainsKey(k)).Where(CanReadBaseValue)) { SetValue(k, GetBaseValue(k)); } SetValue(EntityData.EntityMode, EntityMode.Store); } /// /// Lowlevel Object Cloning while setting the Cloned Enity-Mode to "Store". /// You want to save some data? this maybe your friend... /// /// /// public T Clone() where T : Entity { const EntityData att = EntityData.EntityMode; var val = GetValue(att); if (val.Equals(EntityMode.Refresh)) EntityMode = EntityMode.Store; var obj = new Entity() as T; if (obj != null) { foreach (var o in _datatable.Keys) { var k = o; obj._datatable[k] = _datatable[k]; } obj.EntityMode = (val.Equals(EntityMode.Refresh)) ? EntityMode.Refresh : EntityMode.Store; } if (val.Equals(EntityMode.Refresh)) EntityMode = EntityMode.Refresh; return obj; } } }