Exemple #1
0
        public ItemStack(IEnumerable <IInanimate> thePile)
        {
            if (thePile == null || thePile.Count() == 0)
            {
                FullStackSize = 0;
                Description   = string.Empty;
                Item          = null;
            }

            FullStackSize = thePile.Count();
            Item          = thePile.First().Template <IInanimateTemplate>();

            StringBuilder sb = new StringBuilder();

            IInanimate plainItem = thePile.FirstOrDefault(item => item.Qualities == null || item.Qualities.Count() == 0);

            if (plainItem != null)
            {
                sb.AppendFormattedLine("({0}) {1}", thePile.Count(item => item.Qualities == null || item.Qualities.Count() == 0), Item.Name);
            }

            foreach (IGrouping <string, IInanimate> currentPair in thePile
                     .Where(item => item.Qualities != null && item.Qualities.Count() > 0)
                     .GroupBy(item => string.Join(",", item.Qualities.Select(quality => string.Format("{0}:{1}", quality.Name, quality.Value)))))
            {
                int    count     = currentPair.Count();
                string qualities = currentPair.Key;

                sb.AppendFormattedLine("({0}) {1} [{2}]", count, Item.Name, qualities);
            }

            Description = sb.ToString();
        }
        /// <summary>
        /// Execute a sale
        /// </summary>
        /// <param name="item">the item in question</param>
        /// <param name="price">the sale price</param>
        /// <returns>error or blank</returns>
        public string MakeSale(IMobile customer, IInanimate item, int price)
        {
            string returnString = string.Empty;

            if (customer == null)
            {
                return("Invalid customer");
            }

            if (item == null || !Inventory.Contains(item))
            {
                return("I don't have that item in stock.");
            }

            int customerWallet = customer.GetQuality("Bells");

            if (customerWallet < price)
            {
                return("Insufficient Funds.");
            }

            customer.SetQuality(-1 * price, "Bells", true);
            item.TryMoveTo(customer.GetContainerAsLocation());

            return(returnString);
        }
        /// <summary>
        /// What will the merchant buy this item for
        /// </summary>
        /// <param name="item">the item in question</param>
        /// <returns>the price, -1 indicates they wont buy it</returns>
        public int HaggleCheck(IInanimate item)
        {
            decimal value = -1;

            if (item != null)
            {
                IInanimateTemplate template = item.Template <IInanimateTemplate>();
                if (WillPurchase.Any(merch => merch.Item.Id == item.TemplateId))
                {
                    DataStructure.Gaia.IEconomy theEconomy = CurrentLocation.CurrentZone.GetWorld().Macroeconomy;

                    if (theEconomy != null)
                    {
                        DataStructure.Gaia.IEconomicBasis priceBasis = theEconomy.Bases.FirstOrDefault(basis => basis.ItemType.Id == item.TemplateId);

                        if (priceBasis != null)
                        {
                            value = priceBasis.Basis * priceBasis.Adjustment;
                        }
                        else
                        {
                            value = theEconomy.MakeValuation(template);
                        }

                        foreach (IQuality quality in item.Qualities)
                        {
                            DataStructure.Gaia.IEconomicTrend trend = theEconomy.Trends.FirstOrDefault(trnd => trnd.Quality.Equals(quality.Name, StringComparison.InvariantCultureIgnoreCase));

                            if (trend != null)
                            {
                                value += trend.Basis * trend.Adjustment;
                            }
                            else
                            {
                                value += theEconomy.MakeValuation(template);
                            }
                        }

                        decimal myAdjustments = 1;

                        foreach (IMerchandise adjustment in WillPurchase.Where(merch => merch.Item.Id == item.TemplateId))
                        {
                            if (string.IsNullOrWhiteSpace(adjustment.Quality) || item.Qualities.Any(quality => quality.Name.Equals(adjustment.Quality) &&
                                                                                                    quality.Value.IsBetweenOrEqual(adjustment.QualityRange.Low, adjustment.QualityRange.High)))
                            {
                                myAdjustments += adjustment.MarkRate;
                            }
                        }

                        value += value * myAdjustments;
                    }
                }
            }

            return((int)Math.Truncate(value));
        }
        /// <summary>
        /// Check the price this will be sold for
        /// </summary>
        /// <param name="item">The item in question</param>
        /// <returns>the price, -1 indicates it wont be sold or isn't in stock</returns>
        public int PriceCheck(IInanimate item, bool mustBeInStock)
        {
            decimal value = -1;

            //If we need it in stock but don't have it it's sell price is invalid
            if (item != null && (!mustBeInStock || Inventory.Contains(item)))
            {
                if (WillSell.Any(merch => merch.Item.Id == item.TemplateId))
                {
                    DataStructure.Gaia.IEconomy theEconomy = CurrentLocation.CurrentZone.GetWorld().Macroeconomy;

                    if (theEconomy != null)
                    {
                        DataStructure.Gaia.IEconomicBasis priceBasis = theEconomy.Bases.FirstOrDefault(basis => basis.ItemType.Id == item.TemplateId);

                        if (priceBasis != null)
                        {
                            value = priceBasis.Basis * priceBasis.Adjustment;
                        }
                        else
                        {
                            value = theEconomy.MakeValuation(item.Template <IInanimateTemplate>());
                        }

                        foreach (IQuality quality in item.Qualities)
                        {
                            DataStructure.Gaia.IEconomicTrend trend = theEconomy.Trends.FirstOrDefault(trnd => trnd.Quality.Equals(quality.Name, StringComparison.InvariantCultureIgnoreCase));

                            if (trend != null)
                            {
                                value += trend.Basis * trend.Adjustment;
                            }
                            else
                            {
                                value += theEconomy.MakeValuation(item.Template <IInanimateTemplate>());
                            }
                        }

                        decimal myAdjustments = 1;

                        foreach (IMerchandise adjustment in WillSell.Where(merch => merch.Item.Id == item.TemplateId))
                        {
                            if (string.IsNullOrWhiteSpace(adjustment.Quality) || item.Qualities.Any(quality => quality.Name.Equals(adjustment.Quality) &&
                                                                                                    quality.Value.IsBetweenOrEqual(adjustment.QualityRange.Low, adjustment.QualityRange.High)))
                            {
                                myAdjustments *= adjustment.MarkRate;
                            }
                        }

                        value *= myAdjustments;
                    }
                }
            }

            return((int)Math.Truncate(value));
        }
Exemple #5
0
        /// <summary>
        /// Executes this command
        /// </summary>
        internal override bool ExecutionBody()
        {
            INonPlayerCharacter merchant = (INonPlayerCharacter)Subject;

            if (merchant == null || !merchant.DoISellThings())
            {
                RenderError("There is no merchant that sells items in that direction.");
                return(false);
            }

            IInanimate thing = (IInanimate)Target;

            if (Target == null)
            {
                RenderError("The merchant does not sell that item.");
                return(false);
            }

            int price = merchant.PriceCheck(thing, true);

            if (price <= 0)
            {
                RenderError("The merchant will not sell that item.");
                return(false);
            }

            string errorMessage = merchant.MakeSale((IMobile)Actor, thing, price);

            if (!string.IsNullOrWhiteSpace(errorMessage))
            {
                RenderError(errorMessage);
            }

            ILexicalParagraph toActor = new LexicalParagraph(string.Format("You purchase a $T$ from $S$ for {0}blz.", price));

            ILexicalParagraph toArea = new LexicalParagraph("$A$ makes a purchase from $S$.");

            //TODO: language outputs
            Message messagingObject = new Message(toActor)
            {
                ToOrigin = new List <ILexicalParagraph> {
                    toArea
                }
            };

            messagingObject.ExecuteMessaging(Actor, merchant, thing, OriginLocation.CurrentZone, null);

            return(true);
        }
        /// <summary>
        /// Move an entity into a named container in this
        /// </summary>
        /// <typeparam name="T">the type of the entity to add</typeparam>
        /// <param name="thing">the entity to add</param>
        /// <param name="containerName">the name of the container</param>
        /// <returns>errors</returns>
        public string MoveInto <T>(T thing, string containerName)
        {
            IEnumerable <Type> implimentedTypes = DataUtility.GetAllImplimentingedTypes(typeof(T));

            if (implimentedTypes.Contains(typeof(IInanimate)))
            {
                IInanimate obj = (IInanimate)thing;

                if (Inventory.Contains(obj, containerName))
                {
                    return("That is already in the container");
                }

                string moveError = MoveInto(obj);
                if (!string.IsNullOrWhiteSpace(moveError))
                {
                    return(moveError);
                }

                Inventory.Add(obj, containerName);
                UpsertToLiveWorldCache();

                return(string.Empty);
            }

            if (implimentedTypes.Contains(typeof(IMobile)))
            {
                IMobile obj = (IMobile)thing;

                if (MobilesInside.Contains(obj, containerName))
                {
                    return("That is already in the container");
                }

                string moveError = MoveInto(obj);
                if (!string.IsNullOrWhiteSpace(moveError))
                {
                    return(moveError);
                }

                MobilesInside.Add(obj, containerName);
                UpsertToLiveWorldCache();

                return(string.Empty);
            }

            return("Invalid type to move to container.");
        }
Exemple #7
0
        /// <summary>
        /// Executes this command
        /// </summary>
        public override void Execute()
        {
            INonPlayerCharacter merchant = (INonPlayerCharacter)Subject;

            if (merchant == null || !merchant.DoIBuyThings())
            {
                RenderError("There is no merchant that buys items in that direction.");
                return;
            }

            IInanimate thing = (IInanimate)Target;

            if (Target == null)
            {
                RenderError("That item does not exist.");
                return;
            }

            int price = merchant.HaggleCheck(thing);

            if (price <= 0)
            {
                RenderError("The merchant will not buy that item.");
                return;
            }

            string errorMessage = merchant.MakePurchase((IMobile)Actor, thing, price);

            if (!string.IsNullOrWhiteSpace(errorMessage))
            {
                RenderError(errorMessage);
            }

            ILexicalParagraph toActor = new LexicalParagraph(string.Format("You sell a $T$ to $S$ for {0}blz.", price));

            ILexicalParagraph toArea = new LexicalParagraph("$A$ sells an item to $S$.");

            //TODO: language outputs
            Message messagingObject = new Message(toActor)
            {
                ToOrigin = new List <ILexicalParagraph> {
                    toArea
                }
            };

            messagingObject.ExecuteMessaging(Actor, merchant, thing, OriginLocation.CurrentZone, null);
        }
        /// <summary>
        /// Execute a purchase
        /// </summary>
        /// <param name="item">the item in question</param>
        /// <param name="price">the sale price</param>
        /// <returns>error or blank</returns>
        public string MakePurchase(IMobile customer, IInanimate item, int price)
        {
            string returnString = string.Empty;

            if (customer == null)
            {
                return("Invalid customer");
            }

            if (item == null)
            {
                return("Invalid item.");
            }

            customer.SetQuality(price, "Bells", true);
            item.TryMoveTo(GetContainerAsLocation());

            return(returnString);
        }
Exemple #9
0
        /// <summary>
        /// Executes this command
        /// </summary>
        internal override bool ExecutionBody()
        {
            IInanimate thing = (IInanimate)Subject;

            if (Target == null)
            {
                RenderError("There is no merchant in that direction.");
                return(false);
            }

            INonPlayerCharacter merchant = (INonPlayerCharacter)Target;

            if (merchant == null || (!merchant.DoIBuyThings()))
            {
                RenderError("There is no merchant that buys items in that direction.");
                return(false);
            }

            int price = merchant.HaggleCheck(thing);

            if (price <= 0)
            {
                RenderError("The merchant will not buy that item.");
                return(false);
            }

            ILexicalParagraph toActor = new LexicalParagraph(string.Format("The merchant appraises your {0} at {1}blz.", thing.GetDescribableName(Actor), price));

            ILexicalParagraph toArea = new LexicalParagraph("$T$ looks very closely at $A$'s $S$.");

            //TODO: language outputs
            Message messagingObject = new Message(toActor)
            {
                ToOrigin = new List <ILexicalParagraph> {
                    toArea
                }
            };

            messagingObject.ExecuteMessaging(Actor, thing, merchant, OriginLocation.CurrentZone, null);

            return(true);
        }
Exemple #10
0
        /// <summary>
        /// Move an entity out of this' named container
        /// </summary>
        /// <typeparam name="T">the type of entity to remove</typeparam>
        /// <param name="thing">the entity</param>
        /// <param name="containerName">the name of the container</param>
        /// <returns>errors</returns>
        public string MoveFrom <T>(T thing, string containerName)
        {
            IEnumerable <Type> implimentedTypes = DataUtility.GetAllImplimentingedTypes(typeof(T));

            if (implimentedTypes.Contains(typeof(IInanimate)))
            {
                IInanimate obj = (IInanimate)thing;

                if (!Contents.Contains(obj, containerName))
                {
                    return("That is not in the container");
                }

                Contents.Remove(obj, containerName);
                UpsertToLiveWorldCache();

                return(string.Empty);
            }

            if (implimentedTypes.Contains(typeof(IMobile)))
            {
                IMobile obj = (IMobile)thing;

                if (!MobilesInside.Contains(obj, containerName))
                {
                    return("That is not in the container");
                }

                MobilesInside.Remove(obj, containerName);
                UpsertToLiveWorldCache();

                return(string.Empty);
            }

            return("Invalid type to move from container.");
        }
Exemple #11
0
        /// <summary>
        /// Restores live entity backup from Current
        /// </summary>
        /// <returns>Success state</returns>
        public bool RestoreLiveBackup()
        {
            LiveData liveDataAccessor = new LiveData();

            string currentBackupDirectory = liveDataAccessor.BaseDirectory + liveDataAccessor.CurrentDirectoryName;

            //No backup directory? No live data.
            if (!Directory.Exists(currentBackupDirectory))
            {
                return(false);
            }

            LoggingUtility.Log("World restored from current live INITIATED.", LogChannels.Backup, false);

            try
            {
                //dont load players here
                List <IEntity>     entitiesToLoad   = new List <IEntity>();
                IEnumerable <Type> implimentedTypes = typeof(EntityPartial).Assembly.GetTypes().Where(ty => ty.GetInterfaces().Contains(typeof(IEntity)) &&
                                                                                                      ty.IsClass &&
                                                                                                      !ty.IsAbstract &&
                                                                                                      !ty.GetCustomAttributes <IgnoreAutomatedBackupAttribute>().Any());

                foreach (Type type in implimentedTypes.OrderByDescending(type => type == typeof(Gaia) ? 6 :
                                                                         type == typeof(Zone) ? 5 :
                                                                         type == typeof(Locale) ? 3 :
                                                                         type == typeof(Room) ? 3 :
                                                                         type == typeof(Pathway) ? 2 : 0))
                {
                    if (!Directory.Exists(currentBackupDirectory + type.Name))
                    {
                        continue;
                    }

                    DirectoryInfo entityFilesDirectory = new DirectoryInfo(currentBackupDirectory + type.Name);

                    foreach (FileInfo file in entityFilesDirectory.EnumerateFiles())
                    {
                        entitiesToLoad.Add(liveDataAccessor.ReadEntity(file, type));
                    }
                }

                //Check we found actual data
                if (!entitiesToLoad.Any(ent => ent.GetType() == typeof(Gaia)))
                {
                    throw new Exception("No Worlds found, failover.");
                }

                if (!entitiesToLoad.Any(ent => ent.GetType() == typeof(Zone)))
                {
                    throw new Exception("No zones found, failover.");
                }

                //Shove them all into the live system first
                foreach (IEntity entity in entitiesToLoad.OrderBy(ent => ent.Birthdate))
                {
                    entity.UpsertToLiveWorldCache();
                    entity.KickoffProcesses();
                }

                //We need to pick up any places that aren't already live from the file system incase someone added them during the last session\
                foreach (IGaiaTemplate thing in TemplateCache.GetAll <IGaiaTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IGaia entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IGaia;

                    entityThing.SpawnNewInWorld();
                }

                foreach (IZoneTemplate thing in TemplateCache.GetAll <IZoneTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IZone entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IZone;

                    entityThing.SpawnNewInWorld();
                }

                foreach (ILocaleTemplate thing in TemplateCache.GetAll <ILocaleTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    ILocale entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as ILocale;

                    entityThing.ParentLocation = entityThing.ParentLocation.GetLiveInstance();
                    entityThing.SpawnNewInWorld();
                }

                foreach (IRoomTemplate thing in TemplateCache.GetAll <IRoomTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IRoom entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IRoom;

                    entityThing.ParentLocation = entityThing.Template <IRoomTemplate>().ParentLocation.GetLiveInstance();
                    entityThing.SpawnNewInWorld();
                }

                foreach (IPathwayTemplate thing in TemplateCache.GetAll <IPathwayTemplate>().Where(dt => !entitiesToLoad.Any(ent => ent.TemplateId.Equals(dt.Id) && ent.Birthdate >= dt.LastRevised)))
                {
                    IPathway entityThing = Activator.CreateInstance(thing.EntityClass, new object[] { thing }) as IPathway;

                    entityThing.SpawnNewInWorld();
                }

                //We have the containers contents and the birthmarks from the deserial
                //I don't know how we can even begin to do this type agnostically since the collections are held on type specific objects without some super ugly reflection
                foreach (Room entity in entitiesToLoad.Where(ent => ent.GetType() == typeof(Room)))
                {
                    foreach (IInanimate obj in entity.Contents.EntitiesContained())
                    {
                        IInanimate fullObj = LiveCache.Get <IInanimate>(new LiveCacheKey(obj));
                        entity.MoveFrom(obj);
                        entity.MoveInto(fullObj);
                    }

                    foreach (INonPlayerCharacter obj in entity.MobilesInside.EntitiesContained())
                    {
                        INonPlayerCharacter fullObj = LiveCache.Get <INonPlayerCharacter>(new LiveCacheKey(obj));
                        entity.MoveFrom(obj);
                        entity.MoveInto(fullObj);
                    }
                }

                foreach (NonPlayerCharacter entity in entitiesToLoad.Where(ent => ent.GetType() == typeof(NonPlayerCharacter)))
                {
                    foreach (IInanimate obj in entity.Inventory.EntitiesContained())
                    {
                        IInanimate fullObj = LiveCache.Get <IInanimate>(new LiveCacheKey(obj));
                        entity.MoveFrom(obj);
                        entity.MoveInto(fullObj);
                    }
                }

                foreach (Inanimate entity in entitiesToLoad.Where(ent => ent.GetType() == typeof(Inanimate)))
                {
                    foreach (Tuple <string, IInanimate> obj in entity.Contents.EntitiesContainedByName())
                    {
                        IInanimate fullObj = LiveCache.Get <IInanimate>(new LiveCacheKey(obj.Item2));
                        entity.MoveFrom(obj.Item2);
                        entity.MoveInto(fullObj, obj.Item1);
                    }

                    foreach (Tuple <string, IInanimate> obj in entity.Contents.EntitiesContainedByName())
                    {
                        INonPlayerCharacter fullObj = LiveCache.Get <INonPlayerCharacter>(new LiveCacheKey(obj.Item2));
                        entity.MoveFrom((INonPlayerCharacter)obj.Item2);
                        entity.MoveInto(fullObj, obj.Item1);
                    }
                }

                //We need to poll the WorldMaps here and give all the rooms their coordinates as well as the zones their sub-maps
                ParseDimension();

                LoggingUtility.Log("World restored from current live.", LogChannels.Backup, false);
                return(true);
            }
            catch (Exception ex)
            {
                LoggingUtility.LogError(ex);
            }

            return(false);
        }
Exemple #12
0
        /// <summary>
        /// Restores one character from their Current backup
        /// </summary>
        /// <param name="accountHandle">Global Account Handle for the account</param>
        /// <param name="charID">Which character to load</param>
        /// <returns></returns>
        public IPlayer RestorePlayer(string accountHandle, IPlayerTemplate chr)
        {
            IPlayer newPlayerToLoad = null;

            try
            {
                string currentBackupDirectory = BaseDirectory + accountHandle + "/" + CurrentDirectoryName + chr.Id.ToString() + "/";

                //No backup directory? No live data.
                if (!VerifyDirectory(currentBackupDirectory, false))
                {
                    return(null);
                }

                DirectoryInfo playerDirectory = new DirectoryInfo(currentBackupDirectory);

                byte[] fileData = new byte[0];
                using (FileStream stream = File.Open(currentBackupDirectory + GetPlayerFilename(chr.Id), FileMode.Open))
                {
                    fileData = new byte[stream.Length];
                    stream.Read(fileData, 0, (int)stream.Length);
                }

                //no player file to load, derp
                if (fileData.Length == 0)
                {
                    return(null);
                }

                IPlayer blankEntity = Activator.CreateInstance(chr.EntityClass) as IPlayer;
                newPlayerToLoad = (IPlayer)blankEntity.FromBytes(fileData);

                //bad load, dump it
                if (newPlayerToLoad == null)
                {
                    return(null);
                }

                //We have the player in live cache now so make it move to the right place
                newPlayerToLoad.GetFromWorldOrSpawn();
                newPlayerToLoad.UpsertToLiveWorldCache(true);

                //We'll need one of these per container on players
                if (Directory.Exists(playerDirectory + "Inventory/"))
                {
                    DirectoryInfo inventoryDirectory = new DirectoryInfo(playerDirectory + "Inventory/");

                    foreach (FileInfo file in inventoryDirectory.EnumerateFiles())
                    {
                        IInanimate blankObject = Activator.CreateInstance("NetMud.Data", "NetMud.Data.Game.Inanimate") as IInanimate;

                        IInanimate newObj = (IInanimate)blankObject.FromBytes(ReadFile(file));
                        newObj.UpsertToLiveWorldCache(true);
                        newObj.TryMoveTo(newPlayerToLoad.GetContainerAsLocation());
                    }
                }
            }
            catch (Exception ex)
            {
                LoggingUtility.LogError(ex);
            }

            return(newPlayerToLoad);
        }
        public void DoTheThing(Motivator motivator)
        {
            Accomplisher action = Hypothalamus.HowToDo(motivator);
            bool         wander = false;

            switch (action)
            {
            case Accomplisher.Drink:
                IInanimate waterBottle = Inventory.EntitiesContained().FirstOrDefault(ent => ent.GetQuality("Water") > 0);

                if (waterBottle != null)
                {
                    waterBottle.SetQuality(-1, "Water", true);
                    Hypothalamus.ApplyPressure(Motivator.Thirst, -10);
                    Exhaust(-10);
                }
                else
                {
                    wander = true;
                }
                break;

            case Accomplisher.Eat:
                IInanimate food = Inventory.EntitiesContained().FirstOrDefault(ent => ent.GetQuality("Food") > 0);

                if (food != null)
                {
                    //TODO: turn this into an eat command
                    int foodValue = food.GetQuality("Food");
                    food.Remove();
                    Hypothalamus.ApplyPressure(Motivator.Hunger, -1 * foodValue);
                    Harm(-1 * foodValue);
                }
                else
                {
                    wander = true;
                }
                break;

            case Accomplisher.Sleep:
                //Can't sleep yet
                break;

            case Accomplisher.Speak:
                if (CurrentLocation.CurrentZone != null)
                {
                    CurrentLocation.CurrentZone.BroadcastEvent("$A$ moos.", this);
                }
                break;

            case Accomplisher.Wander:
                wander = true;
                break;
            }

            if (wander)
            {
                Random rand = new Random();
                MovementDirectionType direction = (MovementDirectionType)rand.Next(0, 7);

                //Run the command like anyone else
                //Interpret.Render(direction.ToString(), this);
            }
        }