Esempio n. 1
0
		public override void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount)
		{
			if (m_gameClient.Player == null)
			{
				return;
			}
			
			IList<int> tooltipids = new List<int>();
			
			using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.UpdateIcons)))
			{
				long initPos = pak.Position;
	
				int fxcount = 0;
				int entriesCount = 0;
	
				pak.WriteByte(0); // effects count set in the end
				pak.WriteByte(0); // unknown
				pak.WriteByte(Icons); // unknown
				pak.WriteByte(0); // unknown
	
				foreach (IGameEffect effect in m_gameClient.Player.EffectList)
				{
					if (effect.Icon != 0)
					{
						fxcount++;
						if (changedEffects != null && !changedEffects.Contains(effect))
						{
							continue;
						}
						
						// store tooltip update for gamespelleffect.
						if (ForceTooltipUpdate && (effect is GameSpellEffect))
						{
							Spell spell = ((GameSpellEffect)effect).Spell;
							tooltipids.Add(spell.InternalID);
						}
	
						//						log.DebugFormat("adding [{0}] '{1}'", fxcount-1, effect.Name);
						pak.WriteByte((byte)(fxcount - 1)); // icon index
						pak.WriteByte((effect is GameSpellEffect || effect.Icon > 5000) ? (byte)(fxcount - 1) : (byte)0xff);
						byte ImmunByte = 0;
						if (effect is GameSpellEffect)
						{
							//if (((GameSpellEffect)effect).ImmunityState)
							if (effect is GameSpellAndImmunityEffect && ((GameSpellAndImmunityEffect)effect).ImmunityState)
							{
								ImmunByte = 1;
							}
						}
						pak.WriteByte(ImmunByte);
						// bit 0x08 adds "more..." to right click info
						pak.WriteShort(effect.Icon);
						//pak.WriteShort(effect.IsFading ? (ushort)1 : (ushort)(effect.RemainingTime / 1000));
						pak.WriteShort((ushort)(effect.RemainingTime / 1000));
						if (effect is GameSpellEffect)
							pak.WriteShort((ushort)((GameSpellEffect)effect).Spell.InternalID); //v1.110+ send the spell ID for delve info in active icon
						else
							pak.WriteShort(0);//don't override existing tooltip ids
	
						byte flagNegativeEffect = 0;
						if (effect is StaticEffect)
						{
							if (((StaticEffect)effect).HasNegativeEffect)
							{
								flagNegativeEffect = 1;
							}
						}
						else if (effect is GameSpellEffect)
						{
							if (!((GameSpellEffect)effect).SpellHandler.HasPositiveEffect)
							{
								flagNegativeEffect = 1;
							}
						}
						pak.WriteByte(flagNegativeEffect);
	
						pak.WritePascalString(effect.Name);
						entriesCount++;
					}
				}
	
				int oldCount = lastUpdateEffectsCount;
				lastUpdateEffectsCount = fxcount;
	
				while (oldCount > fxcount)
				{
					pak.WriteByte((byte)(fxcount++));
					pak.Fill(0, 10);
					entriesCount++;
					//					log.DebugFormat("adding [{0}] (empty)", fxcount-1);
				}
	
				if (changedEffects != null)
				{
					changedEffects.Clear();
				}
	
				if (entriesCount == 0)
				{
					return; // nothing changed - no update is needed
				}
	
				pak.Position = initPos;
				pak.WriteByte((byte)entriesCount);
				pak.Seek(0, SeekOrigin.End);
	
				SendTCP(pak);
			}
			
			// force tooltips update
			foreach (int entry in tooltipids)
			{
				if (m_gameClient.CanSendTooltip(24, entry))
					SendDelveInfo(DOL.GS.PacketHandler.Client.v168.DetailDisplayHandler.DelveSpell(m_gameClient, entry));
			}
		}
Esempio n. 2
0
        // 190c+ SendUpdateIcons
        public override void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount)
        {
            if (m_gameClient.Player == null)
            {
                return;
            }

            using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.UpdateIcons)))
            {
                long initPos = pak.Position;

                int fxcount      = 0;
                int entriesCount = 0;
                lock (m_gameClient.Player.EffectList)
                {
                    pak.WriteByte(0);                           // effects count set in the end
                    pak.WriteByte(0);                           // unknown
                    pak.WriteByte(Icons);                       // unknown
                    pak.WriteByte(0);                           // unknown
                    foreach (IGameEffect effect in m_gameClient.Player.EffectList)
                    {
                        if (effect.Icon != 0)
                        {
                            fxcount++;
                            if (changedEffects != null && !changedEffects.Contains(effect))
                            {
                                continue;
                            }
                            //						Log.DebugFormat("adding [{0}] '{1}'", fxcount-1, effect.Name);
                            pak.WriteByte((byte)(fxcount - 1));                             // icon index
                            pak.WriteByte((effect is GameSpellEffect) ? (byte)(fxcount - 1) : (byte)0xff);

                            byte ImmunByte = 0;
                            var  gsp       = effect as GameSpellEffect;
                            if (gsp != null && gsp.IsDisabled)
                            {
                                ImmunByte = 1;
                            }
                            pak.WriteByte(ImmunByte);                             // new in 1.73; if non zero says "protected by" on right click

                            // bit 0x08 adds "more..." to right click info
                            pak.WriteShort(effect.Icon);
                            //pak.WriteShort(effect.IsFading ? (ushort)1 : (ushort)(effect.RemainingTime / 1000));
                            pak.WriteShort((ushort)(effect.RemainingTime / 1000));
                            pak.WriteShort(effect.InternalID);                                  // reference for shift+i or cancel spell
                            byte flagNegativeEffect = 0;
                            if (effect is StaticEffect)
                            {
                                if (((StaticEffect)effect).HasNegativeEffect)
                                {
                                    flagNegativeEffect = 1;
                                }
                            }
                            else if (effect is GameSpellEffect)
                            {
                                if (!((GameSpellEffect)effect).SpellHandler.HasPositiveEffect)
                                {
                                    flagNegativeEffect = 1;
                                }
                            }
                            pak.WriteByte(flagNegativeEffect);
                            pak.WritePascalString(effect.Name);
                            entriesCount++;
                        }
                    }

                    int oldCount = lastUpdateEffectsCount;
                    lastUpdateEffectsCount = fxcount;
                    while (oldCount > fxcount)
                    {
                        pak.WriteByte((byte)(fxcount++));
                        pak.Fill(0, 10);
                        entriesCount++;
                        //					Log.DebugFormat("adding [{0}] (empty)", fxcount-1);
                    }

                    if (changedEffects != null)
                    {
                        changedEffects.Clear();
                    }

                    if (entriesCount == 0)
                    {
                        return;                         // nothing changed - no update is needed
                    }
                    pak.Position = initPos;
                    pak.WriteByte((byte)entriesCount);
                    pak.Seek(0, SeekOrigin.End);

                    SendTCP(pak);
                }
            }
            return;
        }
Esempio n. 3
0
		public override void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount)
		{
			if (m_gameClient.Player == null)
				return;
			using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.UpdateIcons)))
			{
				long initPos = pak.Position;
	
				int fxcount = 0;
				int entriesCount = 0;
				lock (m_gameClient.Player.EffectList)
				{
					pak.WriteByte(0);	// effects count set in the end
					pak.WriteByte(0);	// unknown
					pak.WriteByte(0);	// unknown
					pak.WriteByte(0);	// unknown
					foreach (IGameEffect effect in m_gameClient.Player.EffectList)
					{
						if (effect.Icon != 0)
						{
							fxcount++;
							if (changedEffects != null && !changedEffects.Contains(effect))
								continue;
							//						Log.DebugFormat("adding [{0}] '{1}'", fxcount-1, effect.Name);
							pak.WriteByte((byte)(fxcount - 1)); // icon index
							pak.WriteByte((effect is GameSpellEffect) ? (byte)(fxcount - 1) : (byte)0xff);
							
							byte ImmunByte = 0;
							var gsp = effect as GameSpellEffect;
							if (gsp != null && gsp.IsDisabled)
								ImmunByte = 1;
							pak.WriteByte(ImmunByte); // new in 1.73; if non zero says "protected by" on right click
							
							// bit 0x08 adds "more..." to right click info
							pak.WriteShort(effect.Icon);
							//pak.WriteShort(effect.IsFading ? (ushort)1 : (ushort)(effect.RemainingTime / 1000));
							pak.WriteShort((ushort)(effect.RemainingTime / 1000));
							pak.WriteShort(effect.InternalID);      // reference for shift+i or cancel spell
							pak.WritePascalString(effect.Name);
							entriesCount++;
						}
					}
	
					int oldCount = lastUpdateEffectsCount;
					lastUpdateEffectsCount = fxcount;
					while (oldCount > fxcount)
					{
						pak.WriteByte((byte)(fxcount++));
						pak.Fill(0, 9);
						entriesCount++;
						//					Log.DebugFormat("adding [{0}] (empty)", fxcount-1);
					}
	
					if (changedEffects != null)
						changedEffects.Clear();
	
					if (entriesCount == 0)
						return; // nothing changed - no update is needed
	
					pak.Position = initPos;
					pak.WriteByte((byte)entriesCount);
					pak.Seek(0, SeekOrigin.End);
	
					SendTCP(pak);
					//				Log.Debug("packet sent.");
				}
			}
		}
Esempio n. 4
0
        public override void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount)
        {
            if (m_gameClient.Player == null)
            {
                return;
            }

            IList <int> tooltipids = new List <int>();

            using (GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.UpdateIcons)))
            {
                long initPos = pak.Position;

                int fxcount      = 0;
                int entriesCount = 0;

                pak.WriteByte(0);                 // effects count set in the end
                pak.WriteByte(0);                 // unknown
                pak.WriteByte(Icons);             // unknown
                pak.WriteByte(0);                 // unknown

                foreach (IGameEffect effect in m_gameClient.Player.EffectList)
                {
                    if (effect.Icon != 0)
                    {
                        fxcount++;
                        if (changedEffects != null && !changedEffects.Contains(effect))
                        {
                            continue;
                        }

                        // store tooltip update for gamespelleffect.
                        if (ForceTooltipUpdate && (effect is GameSpellEffect))
                        {
                            Spell spell = ((GameSpellEffect)effect).Spell;
                            tooltipids.Add(spell.InternalID);
                        }

                        //						log.DebugFormat("adding [{0}] '{1}'", fxcount-1, effect.Name);
                        pak.WriteByte((byte)(fxcount - 1));                         // icon index
                        pak.WriteByte((effect is GameSpellEffect || effect.Icon > 5000) ? (byte)(fxcount - 1) : (byte)0xff);

                        byte ImmunByte = 0;
                        var  gsp       = effect as GameSpellEffect;
                        if (gsp != null && gsp.IsDisabled)
                        {
                            ImmunByte = 1;
                        }
                        pak.WriteByte(ImmunByte);                         // new in 1.73; if non zero says "protected by" on right click

                        // bit 0x08 adds "more..." to right click info
                        pak.WriteShort(effect.Icon);
                        //pak.WriteShort(effect.IsFading ? (ushort)1 : (ushort)(effect.RemainingTime / 1000));
                        pak.WriteShort((ushort)(effect.RemainingTime / 1000));
                        if (effect is GameSpellEffect)
                        {
                            pak.WriteShort((ushort)((GameSpellEffect)effect).Spell.InternalID);                             //v1.110+ send the spell ID for delve info in active icon
                        }
                        else
                        {
                            pak.WriteShort(0);                            //don't override existing tooltip ids
                        }
                        byte flagNegativeEffect = 0;
                        if (effect is StaticEffect)
                        {
                            if (((StaticEffect)effect).HasNegativeEffect)
                            {
                                flagNegativeEffect = 1;
                            }
                        }
                        else if (effect is GameSpellEffect)
                        {
                            if (!((GameSpellEffect)effect).SpellHandler.HasPositiveEffect)
                            {
                                flagNegativeEffect = 1;
                            }
                        }
                        pak.WriteByte(flagNegativeEffect);

                        pak.WritePascalString(effect.Name);
                        entriesCount++;
                    }
                }

                int oldCount = lastUpdateEffectsCount;
                lastUpdateEffectsCount = fxcount;

                while (oldCount > fxcount)
                {
                    pak.WriteByte((byte)(fxcount++));
                    pak.Fill(0, 10);
                    entriesCount++;
                    //					log.DebugFormat("adding [{0}] (empty)", fxcount-1);
                }

                if (changedEffects != null)
                {
                    changedEffects.Clear();
                }

                if (entriesCount == 0)
                {
                    return;                     // nothing changed - no update is needed
                }

                pak.Position = initPos;
                pak.WriteByte((byte)entriesCount);
                pak.Seek(0, SeekOrigin.End);

                SendTCP(pak);
            }

            // force tooltips update
            foreach (int entry in tooltipids)
            {
                if (m_gameClient.CanSendTooltip(24, entry))
                {
                    SendDelveInfo(DOL.GS.PacketHandler.Client.v168.DetailDisplayHandler.DelveSpell(m_gameClient, entry));
                }
            }
        }
Esempio n. 5
0
		/// <summary>
		/// SendTrainerWindow method
		/// </summary>
		public override void SendTrainerWindow()
		{
			if (m_gameClient == null || m_gameClient.Player == null) return;

			// type 0 & type 1

			using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow)))
			{
				IList specs = m_gameClient.Player.GetSpecList();
				pak.WriteByte((byte)specs.Count);
				pak.WriteByte((byte)m_gameClient.Player.SkillSpecialtyPoints);
				pak.WriteByte(0);
				pak.WriteByte(0);

				int i = 0;
				foreach (Specialization spec in specs)
				{
					pak.WriteByte((byte)i++);
					pak.WriteByte((byte)Math.Min(50, spec.Level));
					pak.WriteByte((byte)(Math.Min(50, spec.Level) + 1)); 
					pak.WritePascalString(spec.Name);
				}
				SendTCP(pak);
			}

			// realm abilities
			List<RealmAbility> raList = SkillBase.GetClassRealmAbilities(m_gameClient.Player.CharacterClass.ID);
			if (raList != null && raList.Count > 0)
			{
				var offeredRA = new List<RealmAbility>();
				foreach (RealmAbility ra in raList)
				{
					var playerRA = (RealmAbility)m_gameClient.Player.GetAbility(ra.KeyName);
					if (playerRA != null)
					{
						if (playerRA.Level < playerRA.MaxLevel)
						{
							var ab = SkillBase.GetAbility(playerRA.KeyName, playerRA.Level + 1) as RealmAbility;
							if (ab != null)
							{
								offeredRA.Add(ab);
							}
							else
							{
								log.Error("Ability " + ab.Name + " not found!");
							}
						}
					}
					else
					{
						if (ra.Level < ra.MaxLevel)
						{
							offeredRA.Add(ra);
						}
					}
				}

				using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow)))
				{
					pak.WriteByte((byte)offeredRA.Count);
					pak.WriteByte((byte)m_gameClient.Player.RealmSpecialtyPoints);
					pak.WriteByte(1);
					pak.WriteByte(0);

					int i = 0;
					foreach (RealmAbility ra in offeredRA)
					{
						pak.WriteByte((byte)i++);
						pak.WriteByte((byte)ra.Level);
						pak.WriteByte((byte)ra.CostForUpgrade(ra.Level - 1));
						bool canBeUsed = ra.CheckRequirement(m_gameClient.Player);
						pak.WritePascalString((canBeUsed ? "" : "[") + ra.Name + (canBeUsed ? "" : "]"));
					}

					m_gameClient.Player.TempProperties.setProperty("OFFERED_RA", offeredRA);
					SendTCP(pak);
				}
			}

			// type 4 (skills) & type 3 (description)
			GSTCPPacketOut paksub = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow));
			long pos = paksub.Position;
			IList spls = m_gameClient.Player.GetSpellLines();
			IList spcls = m_gameClient.Player.GetSpecList();
			IList<string> autotrains = m_gameClient.Player.CharacterClass.GetAutotrainableSkills();

			paksub.WriteByte(0); //size
			paksub.WriteByte((byte)m_gameClient.Player.SkillSpecialtyPoints);
			paksub.WriteByte(3);
			paksub.WriteByte(0);
			paksub.WriteByte(0);

			// Fill out an array that tells the client how many spec points are available at each of
			// this characters levels.  This seems to only be used for the 'Minimum Level' display on
			// the new trainer window.  I've changed the calls below to use AdjustedSpecPointsMultiplier
			// to enable servers that allow levels > 50 to train properly by modifying points available per level. - Tolakram

			// There is a bug here that is calculating too few spec points and causing level 50 players to 
			// be unable to train RA.  Setting this to max for now to disable 'Minimum Level' feature on train window.
			// I think bug is that auto train points must be added to this calculation.
			// -Tolakram

			for (byte i = 2; i <= 50; i++)
			{
				//int specpoints = 0;

				//if (i <= 5)
				//    specpoints = i;

				//if (i > 5)
				//    specpoints = i * m_gameClient.Player.CharacterClass.AdjustedSpecPointsMultiplier / 10;

				//if (i > 40 && i != 50)
				//    specpoints += i * m_gameClient.Player.CharacterClass.AdjustedSpecPointsMultiplier / 20;

				//paksub.WriteByte((byte)specpoints);
				paksub.WriteByte((byte)255);
			}


			byte count = 0;
			int skillindex = 0;
			Dictionary<string, string> Spec2Line = new Dictionary<string, string>();
			foreach (SpellLine line in spls)
			{
				if (line.IsBaseLine) continue;
				if (!Spec2Line.ContainsKey(line.Spec))
					Spec2Line.Add(line.Spec, line.KeyName);
			}

			foreach (Specialization spc in spcls)
			{
				if (Spec2Line.ContainsKey(spc.KeyName)) //spells
				{
					paksub.WriteByte((byte)skillindex);
					skillindex++;

					using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow)))
					{
						List<Spell> lss = SkillBase.GetSpellList(Spec2Line[spc.KeyName]);

						pak.WriteByte((byte)lss.Count);
						pak.WriteByte((byte)m_gameClient.Player.SkillSpecialtyPoints);
						pak.WriteByte(4);
						pak.WriteByte(0);
						pak.WriteByte(count);
						count += (byte)lss.Count;

						paksub.WriteByte((byte)lss.Count);
						if(autotrains.Contains(spc.KeyName))
							paksub.WriteByte((byte)Math.Floor((double)m_gameClient.Player.BaseLevel / 4));
						else paksub.WriteByte(0);

						foreach (Spell sp in lss)
						{
							pak.WritePascalString(sp.Name);
							paksub.WriteByte((byte)Math.Min(50, sp.Level));
							paksub.WriteShort((ushort)sp.Icon);
							paksub.WriteByte((byte)sp.SkillType);
							paksub.WriteByte(0);	// unk
							paksub.WriteByte((byte)((byte)sp.SkillType == 3 ? 254 : 255));
							paksub.WriteShort((ushort)sp.ID);
						}
						SendTCP(pak);
					}
				}
				else //styles and other
				{
					paksub.WriteByte((byte)skillindex);
					skillindex++;

					List<Style> lst = SkillBase.GetStyleList(spc.KeyName, m_gameClient.Player.CharacterClass.ID);
					if (lst != null && lst.Count > 0) //styles
					{
						using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow)))
						{
							pak.WriteByte((byte)lst.Count);
							pak.WriteByte((byte)m_gameClient.Player.SkillSpecialtyPoints);
							pak.WriteByte(4);
							pak.WriteByte(0);
							pak.WriteByte(count);
							count += (byte)lst.Count;

							paksub.WriteByte((byte)lst.Count);
							if(autotrains.Contains(spc.KeyName))
								paksub.WriteByte((byte)Math.Floor((double)m_gameClient.Player.BaseLevel / 4));
							else paksub.WriteByte(0);

							foreach (var st in lst)
							{
								pak.WritePascalString(st.Name);
								paksub.WriteByte((byte)Math.Min(50, st.Level));
								paksub.WriteShort((ushort)st.Icon);
								paksub.WriteByte((byte)st.SkillType);
								paksub.WriteByte((byte)st.OpeningRequirementType);
								paksub.WriteByte((byte)st.OpeningRequirementValue);
								paksub.WriteShort((ushort)st.ID);
							}
							SendTCP(pak);
						}
					}
					else //other
					{
						using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow)))
						{
							pak.WriteByte(0);
							pak.WriteByte((byte)m_gameClient.Player.SkillSpecialtyPoints);
							pak.WriteByte(4);
							pak.WriteByte(0);
							pak.WriteByte(count);
							SendTCP(pak);
						}

						paksub.WriteByte(0);
						if (autotrains.Contains(spc.KeyName))
							paksub.WriteByte((byte)Math.Floor((double)m_gameClient.Player.BaseLevel / 4));
						else paksub.WriteByte(0);
					}
				}
			}
			paksub.Seek(pos, System.IO.SeekOrigin.Begin);
			paksub.WriteByte((byte)skillindex); //fix size
			paksub.Seek(0, System.IO.SeekOrigin.End);
			SendTCP(paksub);

			// type 5 (realm abilities)
			List<RealmAbility> ras = SkillBase.GetClassRealmAbilities(m_gameClient.Player.CharacterClass.ID);
			using (var pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.TrainerWindow)))
			{
				pak.WriteByte((byte)ras.Count);
				pak.WriteByte((byte)m_gameClient.Player.RealmSpecialtyPoints);
				pak.WriteByte(5);
				pak.WriteByte(0);

				foreach (RealmAbility ra in ras)
				{
					if (ra is RR5RealmAbility)
						continue;

					RealmAbility playerRA = (RealmAbility) m_gameClient.Player.GetAbility(ra.KeyName);
					
					if (playerRA != null)
						pak.WriteByte((byte)(playerRA.Level));

					else
						pak.WriteByte(0);
					
					pak.WriteByte(0);
					pak.WriteByte((byte)ra.MaxLevel);

					for (int i = 0; i < ra.MaxLevel; i++)
						pak.WriteByte((byte)ra.CostForUpgrade(i));

					if (ra.CheckRequirement(m_gameClient.Player))
						pak.WritePascalString(ra.KeyName);
					else
						pak.WritePascalString("[" + ra.Name + "]");
				}
				SendTCP(pak);
			}
		}
Esempio n. 6
0
		public override void SendUpdateIcons(IList changedEffects, ref int lastUpdateEffectsCount)
		{
			if (m_gameClient.Player == null)
			{
				return;
			}
			GSTCPPacketOut pak = new GSTCPPacketOut(GetPacketCode(eServerPackets.UpdateIcons));
			long initPos = pak.Position;

			int fxcount = 0;
			int entriesCount = 0;

			pak.WriteByte(0); // effects count set in the end
			pak.WriteByte(0); // unknown
			pak.WriteByte(Icons); // unknown
			pak.WriteByte(0); // unknown

			foreach (IGameEffect effect in m_gameClient.Player.EffectList)
			{
				if (effect.Icon != 0)
				{
					fxcount++;
					if (changedEffects != null && !changedEffects.Contains(effect))
					{
						continue;
					}

					//						log.DebugFormat("adding [{0}] '{1}'", fxcount-1, effect.Name);
					pak.WriteByte((byte)(fxcount - 1)); // icon index
					pak.WriteByte((effect is GameSpellEffect || effect.Icon > 5000) ? (byte)(fxcount - 1) : (byte)0xff);
					byte ImmunByte = 0;
					if (effect is GameSpellAndImmunityEffect)
					{
						GameSpellAndImmunityEffect immunity = (GameSpellAndImmunityEffect)effect;
						if (immunity.ImmunityState)
						{
							ImmunByte = 1;
						}
					}
					pak.WriteByte(ImmunByte);
					// bit 0x08 adds "more..." to right click info
					pak.WriteShort(effect.Icon);
					pak.WriteShort((ushort)(effect.RemainingTime / 1000));
					if (effect is GameSpellEffect)
						pak.WriteShort(((GameSpellEffect)effect).Spell.ID); //v1.110+ send the spell ID for delve info in active icon
					else
						pak.WriteShort(effect.InternalID);//old method

					byte flagNegativeEffect = 0;
					if (effect is StaticEffect)
					{
						if (((StaticEffect)effect).HasNegativeEffect)
						{
							flagNegativeEffect = 1;
						}
					}
					else if (effect is GameSpellEffect)
					{
						if (!((GameSpellEffect)effect).SpellHandler.HasPositiveEffect)
						{
							flagNegativeEffect = 1;
						}
					}
					pak.WriteByte(flagNegativeEffect);

					pak.WritePascalString(effect.Name);
					entriesCount++;
				}
			}

			int oldCount = lastUpdateEffectsCount;
			lastUpdateEffectsCount = fxcount;

			while (oldCount > fxcount)
			{
				pak.WriteByte((byte)(fxcount++));
				pak.Fill(0, 10);
				entriesCount++;
				//					log.DebugFormat("adding [{0}] (empty)", fxcount-1);
			}

			if (changedEffects != null)
			{
				changedEffects.Clear();
			}

			if (entriesCount == 0)
			{
				return; // nothing changed - no update is needed
			}

			pak.Position = initPos;
			pak.WriteByte((byte)entriesCount);
			pak.Seek(0, SeekOrigin.End);

			SendTCP(pak);
			//				log.Debug("packet sent.");
			return;
		}