private void Regenerate(object state)
            {
                if (RegenerationWorking)
                {
                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.WARNING, "Update: Regenerator skipping update");
                    return;
                }
                RegenerationWorking = true;
                NextGroupUpdate     = !NextGroupUpdate;
                checked
                {
                    try
                    {
                        WorldServiceLocator._WorldServer.CHARACTERs_Lock.AcquireReaderLock(WorldServiceLocator._Global_Constants.DEFAULT_LOCK_TIMEOUT);
                        foreach (KeyValuePair <ulong, WS_PlayerData.CharacterObject> Character in WorldServiceLocator._WorldServer.CHARACTERs)
                        {
                            if (Character.Value.DEAD || Character.Value.underWaterTimer != null || Character.Value.LogoutTimer != null || Character.Value.client == null)
                            {
                                continue;
                            }
                            WS_PlayerData.CharacterObject value = Character.Value;
                            BaseMana    = value.Mana.Current;
                            BaseRage    = value.Rage.Current;
                            BaseEnergy  = value.Energy.Current;
                            BaseLife    = value.Life.Current;
                            _updateFlag = false;
                            if (value.ManaType == ManaTypes.TYPE_RAGE)
                            {
                                switch (value.cUnitFlags & 0x80000)
                                {
                                case 0:
                                    if (value.Rage.Current > 0)
                                    {
                                        value.Rage.Current -= 25;
                                    }

                                    break;

                                default:
                                    if (value.RageRegenBonus != 0)
                                    {
                                        value.Rage.Increment(value.RageRegenBonus);
                                    }

                                    break;
                                }
                            }
                            if (value.ManaType == ManaTypes.TYPE_ENERGY && value.Energy.Current < value.Energy.Maximum)
                            {
                                value.Energy.Increment(20);
                            }
                            if (value.ManaRegen == 0)
                            {
                                value.UpdateManaRegen();
                            }
                            if (value.spellCastManaRegeneration == 0)
                            {
                                if ((value.ManaType == ManaTypes.TYPE_MANA || value.Classe == Classes.CLASS_DRUID) && value.Mana.Current < value.Mana.Maximum)
                                {
                                    value.Mana.Increment(value.ManaRegen * 2);
                                }
                            }
                            else
                            {
                                if ((value.ManaType == ManaTypes.TYPE_MANA || value.Classe == Classes.CLASS_DRUID) && value.Mana.Current < value.Mana.Maximum)
                                {
                                    value.Mana.Increment(value.ManaRegenInterrupt * 2);
                                }
                                if (value.spellCastManaRegeneration < 2)
                                {
                                    value.spellCastManaRegeneration = 0;
                                }
                                else
                                {
                                    value.spellCastManaRegeneration -= 2;
                                }
                            }
                            if (value.Life.Current < value.Life.Maximum && (value.cUnitFlags & 0x80000) == 0)
                            {
                                switch (value.Classe)
                                {
                                case Classes.CLASS_MAGE:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.1 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_PRIEST:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.1 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_WARLOCK:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.11 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_DRUID:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.11 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_SHAMAN:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.11 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_ROGUE:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.5 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_WARRIOR:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.8 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_HUNTER:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.25 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;

                                case Classes.CLASS_PALADIN:
                                    value.Life.Increment((int)Math.Round(value.Spirit.Base * 0.25 * value.LifeRegenerationModifier) + value.LifeRegenBonus);
                                    break;
                                }
                            }
                            if (BaseMana != value.Mana.Current)
                            {
                                _updateFlag            = true;
                                value.GroupUpdateFlag |= 16u;
                                value.SetUpdateFlag(23, value.Mana.Current);
                            }
                            if ((BaseRage != value.Rage.Current) || ((value.cUnitFlags & 0x80000) == 0x80000))
                            {
                                _updateFlag            = true;
                                value.GroupUpdateFlag |= 16u;
                                value.SetUpdateFlag(24, value.Rage.Current);
                            }
                            if (BaseEnergy != value.Energy.Current)
                            {
                                _updateFlag            = true;
                                value.GroupUpdateFlag |= 16u;
                                value.SetUpdateFlag(26, value.Energy.Current);
                            }
                            if (BaseLife != value.Life.Current)
                            {
                                _updateFlag = true;
                                value.SetUpdateFlag(22, value.Life.Current);
                                value.GroupUpdateFlag |= 2u;
                            }
                            if (_updateFlag)
                            {
                                value.SendCharacterUpdate();
                            }
                            if (value.DuelOutOfBounds != 11)
                            {
                                value.DuelOutOfBounds -= 2;
                                if (value.DuelOutOfBounds == 0)
                                {
                                    WorldServiceLocator._WS_Spells.DuelComplete(ref value.DuelPartner, ref value.client.Character);
                                }
                            }
                            value.CheckCombat();
                            if (NextGroupUpdate)
                            {
                                value.GroupUpdate();
                            }
                            if (value.guidsForRemoving.Count > 0)
                            {
                                value.SendOutOfRangeUpdate();
                            }
                            value = null;
                        }
                        if (WorldServiceLocator._WorldServer.CHARACTERs_Lock.IsReaderLockHeld)
                        {
                            WorldServiceLocator._WorldServer.CHARACTERs_Lock.ReleaseReaderLock();
                        }
                    }
                    catch (Exception ex2)
                    {
                        ProjectData.SetProjectError(ex2);
                        Exception ex = ex2;
                        WorldServiceLocator._WorldServer.Log.WriteLine(LogType.WARNING, "Error at regenerate.{0}", Environment.NewLine + ex);
                        ProjectData.ClearProjectError();
                    }
                    RegenerationWorking = false;
                }
            }
Пример #2
0
        private void DoTrade()
        {
            byte TargetReqItems = 0;
            byte TraderReqItems = 0;
            byte i = 0;

            do
            {
                checked
                {
                    if (TraderSlots[i] > 0)
                    {
                        TargetReqItems = (byte)(TargetReqItems + 1);
                    }
                    if (TargetSlots[i] > 0)
                    {
                        TraderReqItems = (byte)(TraderReqItems + 1);
                    }
                    i = (byte)unchecked ((uint)(i + 1));
                }
            }while (i <= 5u);
            try
            {
                if (Target.ItemFREESLOTS() < TargetReqItems)
                {
                    Packets.PacketClass responseUnAccept2 = new(Opcodes.SMSG_TRADE_STATUS);
                    try
                    {
                        responseUnAccept2.AddInt32(7);
                        Target.client.SendMultiplyPackets(ref responseUnAccept2);
                        TraderAccept = false;
                        Trader.client.SendMultiplyPackets(ref responseUnAccept2);
                        TraderAccept = false;
                    }
                    finally
                    {
                        responseUnAccept2.Dispose();
                    }
                    Packets.PacketClass responseNoSlot2 = new(Opcodes.SMSG_INVENTORY_CHANGE_FAILURE);
                    try
                    {
                        responseNoSlot2.AddInt8(50);
                        responseNoSlot2.AddUInt64(0uL);
                        responseNoSlot2.AddUInt64(0uL);
                        responseNoSlot2.AddInt8(0);
                        Target.client.Send(ref responseNoSlot2);
                    }
                    finally
                    {
                        responseNoSlot2.Dispose();
                    }
                    return;
                }
                if (Trader.ItemFREESLOTS() < TraderReqItems)
                {
                    Packets.PacketClass responseUnAccept = new(Opcodes.SMSG_TRADE_STATUS);
                    try
                    {
                        responseUnAccept.AddInt32(7);
                        Target.client.SendMultiplyPackets(ref responseUnAccept);
                        TraderAccept = false;
                        Trader.client.SendMultiplyPackets(ref responseUnAccept);
                        TargetAccept = false;
                    }
                    finally
                    {
                        responseUnAccept.Dispose();
                    }
                    Packets.PacketClass responseNoSlot = new(Opcodes.SMSG_INVENTORY_CHANGE_FAILURE);
                    try
                    {
                        responseNoSlot.AddInt8(50);
                        responseNoSlot.AddUInt64(0uL);
                        responseNoSlot.AddUInt64(0uL);
                        responseNoSlot.AddInt8(0);
                        Trader.client.Send(ref responseNoSlot);
                    }
                    finally
                    {
                        responseNoSlot.Dispose();
                    }
                    return;
                }
                if ((TargetGold > 0L) || (TraderGold > 0L))
                {
                    checked
                    {
                        Trader.Copper = Trader.Copper - TraderGold + TargetGold;
                        Target.Copper = Target.Copper + TraderGold - TargetGold;
                        Trader.SetUpdateFlag(1176, Trader.Copper);
                        Target.SetUpdateFlag(1176, Target.Copper);
                    }
                }
                if (TargetReqItems > 0 || TraderReqItems > 0)
                {
                    byte j = 0;
                    do
                    {
                        checked
                        {
                            if (TraderSlots[j] > 0)
                            {
                                var        mySlot2 = (byte)(TraderSlots[j] & 0xFF);
                                var        myBag2  = (byte)(TraderSlots[j] >> 8);
                                ItemObject myItem2 = null;
                                myItem2 = (myBag2 != 0) ? Trader.Items[myBag2].Items[mySlot2] : Trader.Items[mySlot2];
                                if (myItem2.ItemInfo.ObjectClass != ITEM_CLASS.ITEM_CLASS_QUEST)
                                {
                                    myItem2.OwnerGUID = Target.GUID;
                                    if (Target.ItemADD(ref myItem2))
                                    {
                                        Trader.ItemREMOVE(myBag2, mySlot2, Destroy: false, Update: false);
                                    }
                                }
                            }
                            if (TargetSlots[j] > 0)
                            {
                                var        mySlot = (byte)(TargetSlots[j] & 0xFF);
                                var        myBag  = (byte)(TargetSlots[j] >> 8);
                                ItemObject myItem = null;
                                myItem = (myBag != 0) ? Target.Items[myBag].Items[mySlot] : Target.Items[mySlot];
                                if (myItem.ItemInfo.ObjectClass != ITEM_CLASS.ITEM_CLASS_QUEST)
                                {
                                    myItem.OwnerGUID = Trader.GUID;
                                    if (Trader.ItemADD(ref myItem))
                                    {
                                        Target.ItemREMOVE(myBag, mySlot, Destroy: false, Update: false);
                                    }
                                }
                            }
                            j = (byte)unchecked ((uint)(j + 1));
                        }
                    }while (j <= 5u);
                }
                Trader.SendCharacterUpdate();
                Target.SendCharacterUpdate();
                Packets.PacketClass response = new(Opcodes.SMSG_TRADE_STATUS);
                try
                {
                    response.AddInt32(8);
                    Target.client.SendMultiplyPackets(ref response);
                    Trader.client.SendMultiplyPackets(ref response);
                }
                finally
                {
                    response.Dispose();
                    Dispose();
                }
            }
            catch (Exception e)
            {
                WorldServiceLocator._WorldServer.Log.WriteLine(LogType.FAILED, "Error doing trade: {0}{1}", Environment.NewLine, e.ToString());
            }
        }
Пример #3
0
        public void GoToNearestGraveyard(ref WS_PlayerData.CharacterObject Character, bool Alive, bool Teleport)
        {
            DataTable  GraveQuery = new DataTable();
            bool       foundNear  = false;
            float      distNear   = 0f;
            TGraveyard entryNear  = default;
            TGraveyard entryFar   = default;

            checked
            {
                if (WorldServiceLocator._WS_Maps.Maps[Character.MapID].IsDungeon | WorldServiceLocator._WS_Maps.Maps[Character.MapID].IsBattleGround | WorldServiceLocator._WS_Maps.Maps[Character.MapID].IsRaid)
                {
                    Character.ZoneCheckInstance();
                    int Ghostzone = WorldServiceLocator._WS_Maps.AreaTable[WorldServiceLocator._WS_Maps.GetAreaIDByMapandParent((int)Character.MapID, WorldServiceLocator._WS_Maps.AreaTable[WorldServiceLocator._WS_Maps.GetAreaFlag(Character.resurrectPositionX, Character.resurrectPositionY, (int)Character.MapID)].Zone)].ID;
                    WorldServiceLocator._WorldServer.WorldDatabase.Query($"SELECT id, faction FROM game_graveyard_zone WHERE ghost_zone = {Ghostzone} and (faction = 0 or faction = {Character.Team}) ", ref GraveQuery);
                    if (GraveQuery.Rows.Count == 0)
                    {
                        WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYards: No near graveyards for map [{0}], zone [{1}]", Character.MapID, Character.ZoneID);
                        return;
                    }
                    if (WorldServiceLocator._WS_Maps.Maps[Character.MapID].IsDungeon | WorldServiceLocator._WS_Maps.Maps[Character.MapID].IsBattleGround | WorldServiceLocator._WS_Maps.Maps[Character.MapID].IsRaid)
                    {
                        if (Graveyards.ContainsKey(Conversions.ToInteger(GraveQuery.Rows[0]["id"])))
                        {
                            entryFar  = Graveyards[Conversions.ToInteger(GraveQuery.Rows[0]["id"])];
                            entryNear = entryFar;
                        }
                        else
                        {
                            WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYard: {0} is missing for map [{1}], zone [{2}]", GraveQuery.Rows[0]["id"], Character.MapID, Character.ZoneID);
                        }
                    }
                    else
                    {
                        IEnumerator enumerator = default;
                        try
                        {
                            enumerator = GraveQuery.Rows.GetEnumerator();
                            while (enumerator.MoveNext())
                            {
                                DataRow row               = (DataRow)enumerator.Current;
                                int     GraveyardID2      = row.As <int>("id");
                                int     GraveyardFaction2 = row.As <int>("faction");
                                if (!Graveyards.ContainsKey(GraveyardID2))
                                {
                                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYards: Graveyard link invalid [{0}]", GraveyardID2);
                                }
                                else if (Character.MapID != Graveyards[GraveyardID2].Map)
                                {
                                    if (Information.IsNothing(entryFar))
                                    {
                                        entryFar = Graveyards[GraveyardID2];
                                    }
                                }
                                else
                                {
                                    if (GraveyardFaction2 != 0 && GraveyardFaction2 != Character.Team)
                                    {
                                        continue;
                                    }
                                    float dist3 = WorldServiceLocator._WS_Combat.GetDistance(Character.positionX, Graveyards[GraveyardID2].X, Character.positionY, Graveyards[GraveyardID2].Y, Character.positionZ, Graveyards[GraveyardID2].Z);
                                    if (foundNear)
                                    {
                                        if (dist3 < distNear)
                                        {
                                            distNear  = dist3;
                                            entryNear = Graveyards[GraveyardID2];
                                        }
                                    }
                                    else
                                    {
                                        foundNear = true;
                                        distNear  = dist3;
                                        entryNear = Graveyards[GraveyardID2];
                                    }
                                }
                            }
                        }
                        finally
                        {
                            if (enumerator is IDisposable)
                            {
                                (enumerator as IDisposable).Dispose();
                            }
                        }
                    }
                    TGraveyard selectedGraveyard2 = entryNear;
                    if (Information.IsNothing(selectedGraveyard2))
                    {
                        selectedGraveyard2 = entryFar;
                    }
                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYards: GraveYard.Map[{0}], GraveYard.X[{1}], GraveYard.Y[{2}], GraveYard.Z[{3}]", selectedGraveyard2.Map, selectedGraveyard2.X, selectedGraveyard2.Y, selectedGraveyard2.Z);
                    Character.Teleport(selectedGraveyard2.X, selectedGraveyard2.Y, selectedGraveyard2.Z, 0f, selectedGraveyard2.Map);
                    Character.SendDeathReleaseLoc(selectedGraveyard2.X, selectedGraveyard2.Y, selectedGraveyard2.Z, selectedGraveyard2.Map);
                    return;
                }
                Character.ZoneCheck();
                WorldServiceLocator._WorldServer.WorldDatabase.Query($"SELECT id, faction FROM game_graveyard_zone WHERE ghost_zone = {Character.ZoneID}", ref GraveQuery);
                if (GraveQuery.Rows.Count == 0)
                {
                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYards: No near graveyards for map [{0}], zone [{1}]", Character.MapID, Character.ZoneID);
                    return;
                }
                IEnumerator enumerator2 = default;
                try
                {
                    enumerator2 = GraveQuery.Rows.GetEnumerator();
                    while (enumerator2.MoveNext())
                    {
                        DataRow row              = (DataRow)enumerator2.Current;
                        int     GraveyardID      = row.As <int>("id");
                        int     GraveyardFaction = row.As <int>("faction");
                        if (!Graveyards.ContainsKey(GraveyardID))
                        {
                            WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYards: Graveyard link invalid [{0}]", GraveyardID);
                        }
                        else if (Character.MapID != Graveyards[GraveyardID].Map)
                        {
                            if (Information.IsNothing(entryFar))
                            {
                                entryFar = Graveyards[GraveyardID];
                            }
                        }
                        else
                        {
                            if (GraveyardFaction != 0 && GraveyardFaction != Character.Team)
                            {
                                continue;
                            }
                            float dist2 = WorldServiceLocator._WS_Combat.GetDistance(Character.positionX, Graveyards[GraveyardID].X, Character.positionY, Graveyards[GraveyardID].Y, Character.positionZ, Graveyards[GraveyardID].Z);
                            if (foundNear)
                            {
                                if (dist2 < distNear)
                                {
                                    distNear  = dist2;
                                    entryNear = Graveyards[GraveyardID];
                                }
                            }
                            else
                            {
                                foundNear = true;
                                distNear  = dist2;
                                entryNear = Graveyards[GraveyardID];
                            }
                        }
                    }
                }
                finally
                {
                    if (enumerator2 is IDisposable)
                    {
                        (enumerator2 as IDisposable).Dispose();
                    }
                }
                TGraveyard selectedGraveyard = entryNear;
                if (Information.IsNothing(selectedGraveyard))
                {
                    selectedGraveyard = entryFar;
                }
                if (Teleport)
                {
                    if (Alive & Character.DEAD)
                    {
                        WorldServiceLocator._WS_Handlers_Misc.CharacterResurrect(ref Character);
                        Character.Life.Current = Character.Life.Maximum;
                        if (Character.ManaType == ManaTypes.TYPE_MANA)
                        {
                            Character.Mana.Current = Character.Mana.Maximum;
                        }
                        if (selectedGraveyard.Map == Character.MapID)
                        {
                            Character.SetUpdateFlag(22, Character.Life.Current);
                            if (Character.ManaType == ManaTypes.TYPE_MANA)
                            {
                                Character.SetUpdateFlag(23, Character.Mana.Current);
                            }
                            Character.SendCharacterUpdate();
                        }
                    }
                    WorldServiceLocator._WorldServer.Log.WriteLine(LogType.INFORMATION, "GraveYards: GraveYard.Map[{0}], GraveYard.X[{1}], GraveYard.Y[{2}], GraveYard.Z[{3}]", selectedGraveyard.Map, selectedGraveyard.X, selectedGraveyard.Y, selectedGraveyard.Z);
                    Character.Teleport(selectedGraveyard.X, selectedGraveyard.Y, selectedGraveyard.Z, 0f, selectedGraveyard.Map);
                    Character.SendDeathReleaseLoc(selectedGraveyard.X, selectedGraveyard.Y, selectedGraveyard.Z, selectedGraveyard.Map);
                }
                else
                {
                    Character.positionX = selectedGraveyard.X;
                    Character.positionY = selectedGraveyard.Y;
                    Character.positionZ = selectedGraveyard.Z;
                    Character.MapID     = (uint)selectedGraveyard.Map;
                }
            }
        }