/// <summary>Persists all player data to the database. Thread safe. Call in a background thread if the save isn't needed immediately.</summary>
        /// <returns>True if successful, else false.</returns>
        internal override void Save()
        {
            lock (_saveLock) {
                using (EmuDataContext dbCtx = new EmuDataContext()) {
                    DataLoadOptions dlo = new DataLoadOptions();
                    dlo.LoadWith<Character>(c => c.InventoryItems);
                    dbCtx.LoadOptions = dlo;
                    //dbCtx.Log = new Log4NetWriter(typeof(ZonePlayer));

                    Character toon = dbCtx.Characters.SingleOrDefault(c => c.Name == this.Name);
                    toon.X = this.X;
                    toon.Y = this.Y;
                    toon.Z = this.Z;
                    toon.Heading = this.Heading;
                    toon.ZoneID = this.ZoneId;
                    toon.LastSeenDate = DateTime.Now;
                    toon.Platinum = this.Platinum;
                    toon.Gold = this.Gold;
                    toon.Silver = this.Silver;
                    toon.Copper = this.Copper;
                    toon.XP = _pp.XP;   // Going direct to the pp eliminates a cast
                    toon.CharLevel = this.Level;
                    toon.HP = this.HP;

                    // Convert skill values from the uint[] to a byte[]
                    byte[] skills = new byte[toon.Skills.Length];
                    for (int i = 0; i < _pp.Skills.Length; i++)
                        skills[i] = (byte)_pp.Skills[i];
                    toon.Skills = Encoding.ASCII.GetString(skills);

                    // Clear and then re-add the inventory, spellbook, mem'd spells (got a better idea?)
                    dbCtx.InventoryItems.DeleteAllOnSubmit(toon.InventoryItems);    // TODO: this gens many DELETE statements... could be improved
                    dbCtx.MemorizedSpells.DeleteAllOnSubmit(toon.MemorizedSpells);
                    dbCtx.ScribedSpells.DeleteAllOnSubmit(toon.ScribedSpells);
                    dbCtx.SubmitChanges();

                    foreach (InventoryItem invItem in this.InvMgr.AllItems()) {
                        //_log.DebugFormat("During save found item {0} in slot {1}", invItem.Item.Name, invItem.SlotID);
                        toon.InventoryItems.Add(invItem.ShallowCopy());
                    }

                    // Save spellbook
                    for (short i = 0; i < this.PlayerProfile.SpellBook.Length; i++) {
                        if (this.PlayerProfile.SpellBook[i] != Spell.BLANK_SPELL)   // Don't save blank spells
                            toon.ScribedSpells.Add(new ScribedSpell() { SlotID = i, SpellID = (ushort)this.PlayerProfile.SpellBook[i] });
                    }

                    // Save memorized spells
                    for (byte i = 0; i < this.PlayerProfile.MemSpells.Length; i++) {
                        if (this.PlayerProfile.MemSpells[i] != Spell.BLANK_SPELL)   // Don't save blank spells
                            toon.MemorizedSpells.Add(new MemorizedSpell() { SlotID = i, SpellID = (ushort)this.PlayerProfile.MemSpells[i] });
                    }

                    dbCtx.SubmitChanges();

                    // TODO: save cursor items
                }
            }

            _log.DebugFormat("{0} Saved.", this.Name);
        }
Beispiel #2
0
        internal static bool Delete(string charName)
        {
            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                Data.Character charToDel = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
                if (charToDel != null)
                {
                    dbCtx.Characters.DeleteOnSubmit(charToDel);
                    dbCtx.SubmitChanges();
                    return true;
                }
            }

            return false;
        }
Beispiel #3
0
        internal static bool ReserveName(int acctId, string name)
        {
            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                if (dbCtx.Characters.Count(c => c.Name == name) > 0)
                    return false;

                Character toon = new Character();
                toon.AccountID = acctId;
                toon.Name = name;
                toon.CreatedDate = DateTime.Now;
                dbCtx.Characters.InsertOnSubmit(toon);
                dbCtx.SubmitChanges();
            }

            return true;
        }
Beispiel #4
0
        internal static void Create(string charName, CharacterCreate charCreateStruct)
        {
            // TODO: old emu does some in depth validation of race/class combinations and ability scores.  Will add later if necessary

            using (EmuDataContext dbCtx = new EmuDataContext())
            {
                DataLoadOptions dlo = new DataLoadOptions();
                dlo.LoadWith<StartingItem>(si => si.Item);
                dbCtx.LoadOptions = dlo;

                Character toon = dbCtx.Characters.SingleOrDefault(c => c.Name == charName);
                toon.Race = (short)charCreateStruct.Race;
                toon.Class = (byte)charCreateStruct.Class;
                toon.Gender = (byte)charCreateStruct.Gender;
                toon.Deity = (int)charCreateStruct.Deity;
                toon.STR = (short)charCreateStruct.STR;
                toon.STA = (short)charCreateStruct.STA;
                toon.AGI = (short)charCreateStruct.AGI;
                toon.DEX = (short)charCreateStruct.DEX;
                toon.WIS = (short)charCreateStruct.WIS;
                toon.INT = (short)charCreateStruct.INT;
                toon.CHA = (short)charCreateStruct.CHA;
                toon.Face = (byte)charCreateStruct.Face;
                toon.EyeColor1 = (byte)charCreateStruct.EyeColor1;
                toon.EyeColor2 = (byte)charCreateStruct.EyeColor2;
                toon.HairStyle = (byte)charCreateStruct.HairStyle;
                toon.HairColor = (byte)charCreateStruct.HairColor;
                toon.Beard = (byte)charCreateStruct.Beard;
                toon.BeardColor = (byte)charCreateStruct.BeardColor;
                toon.LastSeenDate = DateTime.Now;
                toon.CharLevel = 1;
                toon.PracticePoints = 5;
                toon.HP = 1000;     // just here for dev, later will be set elsewhere
                toon.HungerLevel = 6000;
                toon.ThirstLevel = 6000;
                toon.Platinum = (uint)EQEmulator.Servers.WorldServer.ServerConfig.StartingPlat;
                toon.Gold = (uint)EQEmulator.Servers.WorldServer.ServerConfig.StartingGold;

                SetRacialStartingAbilities(ref toon);   // Sets languages and skills that are racially determined
                SetClassStartingAbilities(ref toon);    // Sets skills determined by class

                // Get the character's start zone
                StartZone startZone = dbCtx.StartZones.SingleOrDefault(sz => sz.PlayerChoice == charCreateStruct.StartZone
                    && sz.PlayerClass == charCreateStruct.Class && sz.PlayerDeity == charCreateStruct.Deity && sz.PlayerRace == charCreateStruct.Race);
                CharacterBind cb = new CharacterBind();
                toon.X = toon.Y = toon.Z = 0.0F;
                cb.X = cb.Y = cb.Z = 0.0F;
                toon.Heading = 0.0F;

                if (startZone != null)  // TODO: should heading for zone and bind be set to some default setting?
                {
                    // Found a start zone in the db... load up the bind info from that
                    toon.ZoneID = startZone.ZoneID;
                    toon.ZoneName = startZone.Zone.ShortName;
                    toon.X = startZone.X;
                    toon.Y = startZone.Y;
                    toon.Z = startZone.Z;

                    if (startZone.BindZoneID != null)
                    {
                        cb.ZoneID = startZone.BindZoneID.Value;
                        cb.X = startZone.BindX.Value;
                        cb.Y = startZone.BindY.Value;
                        cb.Z = startZone.BindZ.Value;
                    }
                    else
                        cb.ZoneID = startZone.ZoneID;
                }
                else
                    SetDefaultStartZone(charCreateStruct.StartZone, ref toon, ref cb);

                Zone zone = null;

                // Load safe points for start zone coords if necessary
                if (toon.X == 0.0F && toon.Y == 0.0F && toon.Z == 0.0F)
                {
                    zone = dbCtx.Zones.SingleOrDefault(z => z.ZoneID == toon.ZoneID);
                    toon.X = zone.SafeX;
                    toon.Y = zone.SafeY;
                    toon.Z = zone.SafeZ;
                }

                // Load safe points for start bind coords if necessary
                if (cb.X == 0.0F && cb.Y == 0.0F && cb.Z == 0.0F)
                {
                    zone = dbCtx.Zones.SingleOrDefault(z => z.ZoneID == cb.ZoneID);
                    if (zone != null)
                    {
                        cb.X = zone.SafeX;
                        cb.Y = zone.SafeY;
                        cb.Z = zone.SafeZ;
                    }
                    else
                        _log.ErrorFormat("Unable to load safe points for bind zone {0}", cb.ZoneID);
                }

                cb.Heading = toon.Heading.Value;
                toon.CharacterBinds.Add(cb);

                // Get starting items
                var startingItems = from si in dbCtx.StartingItems
                                    where (si.Race == toon.Race.Value || si.Race == 0) && (si.Class == toon.Class.Value || si.Class == 0)
                                    && (si.DeityID == (toon.Deity ?? 0) || si.DeityID == 0) && (si.ZoneID == toon.ZoneID.Value || si.ZoneID == 0)
                                    select si;

                int siSlotId = 22;    // for initial items with unspecified slots, just dump them to the personal inv slots
                foreach (StartingItem si in startingItems) {
                    InventoryItem ii = new InventoryItem {
                        ItemID = si.ItemID,
                        Charges = si.ItemCharges,
                        Color = si.Item.Color ?? 0,
                        SlotID = si.Slot
                    };

                    if (ii.SlotID < 0) {  // for unspecified inventory slots, find an open slot
                        ii.SlotID = siSlotId;
                        siSlotId++;
                    }

                    toon.InventoryItems.Add(ii);
                }

                dbCtx.SubmitChanges();
            }
        }