|
#region ShadowClone
#region ShadowClone
case 12090:
{
attacker.AttackPacket = null;
if (attacker.MyClones.Count > 0)
{
var clones = attacker.MyClones.Values.ToArray();
for (int i = 0; i < clones.Length; i++)
{
var item = clones[i];
if (item == null)
continue;
Data data = new Data(true);
data.UID = item.UID;
data.ID = Network.GamePackets.Data.RemoveEntity;
attacker.Owner.SendScreen(data);
attacker.MyClones[item.UID] = null;
}
attacker.MyClones.Clear();
}
else
{
if (CanUseSpell(spell, attacker.Owner))
{
PrepareSpell(spell, attacker.Owner);
SpellUse spellUse = new SpellUse(true);
spellUse.Attacker = attacker.UID;
spellUse.SpellID = spell.ID;
spellUse.SpellLevel = spell.Level;
spellUse.X = X;
spellUse.Y = Y;
attacker.AddClone(3);
if (spell.Level >= 4)
attacker.AddClone(10003);
foreach (var item in attacker.MyClones.Values)
spellUse.AddTarget(item, 0, attack);
attacker.Owner.SendScreen(spellUse, true);
}
}
break;
}
#endregion
public SafeDictionary<uint, Entity> MyClones = new SafeDictionary<uint, Entity>();
public bool IsClone = false;
public void AddClone(ushort cloneid)
{
#region SpawnPacket(10014)
var Entity = new Entity(EntityFlag.Entity, true);
Entity.MonsterInfo = new MonsterInformation();
MonsterInformation.MonsterInformations.TryGetValue(9003, out Entity.MonsterInfo);
Entity.Owner = Owner;
Entity.MonsterInfo.Owner = Entity;
Entity.IsClone = true;
Entity._Name = "ShadowClone";
Entity.clan = Name;
Entity.SpawnPacket = new byte[8 + _Names + _Name.Length + 36];
Array.Copy(SpawnPacket, Entity.SpawnPacket, Entity.SpawnPacket.Length);
WriteStringList(new List<string>() { "ShadowClone", "", "", Name, "" }, _Names, Entity.SpawnPacket);
Entity.Mesh = Mesh;
Entity.Hitpoints = 1;
Entity.UID = Owner.Map.CloneCounter.Next;
Entity.GuildID = Entity.GuildRank = Entity.Action = 0;
Entity.CountryID = Enums.CountryID.Default;
Entity.StatusFlag = Entity.StatusFlag2 = Entity.StatusFlag3 = Entity.StatusFlag4 = 0;
Writer.Write((uint)0, Game.ConquerStructures.Equipment.Steed, Entity.SpawnPacket);
Writer.Write((uint)0, Game.ConquerStructures.Equipment.SteedPlus, Entity.SpawnPacket);
Writer.Write((uint)0, Game.ConquerStructures.Equipment.SteedColor, Entity.SpawnPacket);
Writer.Write((uint)0, Game.ConquerStructures.Equipment.MountArmor, Entity.SpawnPacket);
Writer.Write((uint)0, Game.ConquerStructures.Equipment.Wing, Entity.SpawnPacket);
Writer.Write((uint)0, Game.ConquerStructures.Equipment.WingPlus, Entity.SpawnPacket);
Entity.FlowerRank = 0;
Entity.NobilityRank = ConquerStructures.NobilityRank.Serf;
Entity.Class = Entity.FirstRebornClass = Entity.SecondRebornClass = Entity.JiangTalent = Entity.SubClassesActive = Entity.Reborn = Entity.Level = Entity.ServerID = 0;
Writer.Write((byte)2, 271, Entity.SpawnPacket);
Writer.Write(cloneid, 272, Entity.SpawnPacket);
Entity.OwnerUID = UID;
Entity.JiangActive = false;
Writer.Write((uint)0, 178, Entity.SpawnPacket);
Writer.Write((uint)0, 182, Entity.SpawnPacket);
Writer.Write((uint)0, 186, Entity.SpawnPacket);
Writer.Write((uint)0, _UnionExploits, Entity.SpawnPacket);
Writer.Write((uint)0, _UnionID, Entity.SpawnPacket);
Writer.Write((uint)0, _UnionRank, Entity.SpawnPacket);
Writer.Write((uint)0, _UnionType, Entity.SpawnPacket);
Writer.Write((uint)0, _MyTitle, Entity.SpawnPacket);
Writer.Write((uint)0, _MyTitleScore, Entity.SpawnPacket);
Writer.Write((uint)0, _MyWing, Entity.SpawnPacket);
Entity.MinAttack = MinAttack;
Entity.MaxAttack = Entity.MagicAttack = Math.Max(MinAttack, MaxAttack);
Entity.Appearance = Appearance;
Entity.MapID = Owner.Map.ID;
Entity.SendUpdates = true;
#endregion SpawnPacket(10014)
#region Pet(2035)
MsgPetInfo pet = new MsgPetInfo();
pet.UID = Entity.UID;
pet.PetID = cloneid;
pet.PetType = 2;
pet.Mesh = Mesh;
pet.AttackRange = (byte)AttackRange;
pet.X = X;
pet.Y = Y;
pet.Name = "ShadowClone";
Owner.Send(pet);
#endregion Pet(2035)
MyClones.Add(Entity.UID, Entity);
Owner.SendScreen(Entity.SpawnPacket, true);
Owner.SendScreenSpawn(Entity, true);
#region Data(10010)
Data data = new Data(true);
data.UID = Entity.UID;
data.Facing = Entity.Facing;
data.ID = Data.AddEntity;
data.wParam1 = Entity.X;
data.wParam2 = Entity.Y;
Owner.Send(data);
#endregion Data(10010)
}
public void Reload(Interfaces.IPacket spawnWith = null)
#region Other Pet & Clones
#region Other Pet & Clones
if (pClient.Entity.MyClones.Count > 0)
{
foreach (var clone in pClient.Entity.MyClones.Values)
{
if (clone == null) continue;
if (Kernel.GetDistance(clone.X, clone.Y, Owner.Entity.X, Owner.Entity.Y) <= 18 && !Contains(clone.UID))
{
if (!clone.Dead)
clone.SendSpawn(Owner);
}
}
}
if (pClient.Pet.Pets.Count > 0)
{
foreach (var pet in pClient.Pet.Pets.Values)
{
if (pet == null) continue;
if (pet.Entity == null) continue;
if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, Owner.Entity.X, Owner.Entity.Y) <= 18 && !Contains(pet.Entity.UID))
{
if (!pet.Entity.Dead)
pet.Entity.SendSpawn(Owner);
}
}
}
#endregion
#region My Pet & Clones
#region My Pet & Clones
if (Owner.Entity.MyClones.Count > 0)
{
foreach (var clone in Owner.Entity.MyClones.Values)
{
if (clone == null) continue;
if (Kernel.GetDistance(clone.X, clone.Y, Owner.Entity.X, Owner.Entity.Y) <= 18 && !Contains(clone.UID))
{
if (!clone.Dead)
clone.SendSpawn(Owner);
}
}
}
if (Owner.Pet.Pets.Count > 0)
{
foreach (var pet in Owner.Pet.Pets.Values)
{
if (pet == null) continue;
if (pet.Entity == null) continue;
if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, Owner.Entity.X, Owner.Entity.Y) <= 18/* && !Contains(pet.Entity.UID)*/)
{
if (!pet.Entity.Dead)
Owner.Send(pet.Entity.SpawnPacket);
// pet.Entity.SendSpawn(Owner, false);
}
}
}
#endregion
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MrHassan.Client;
using MrHassan.Game;
using System.Threading.Generic;
using MrHassan.Database;
using MrHassan.Network.GamePackets;
using MrHassan.Network;
using MrHassan.Game.ConquerStructures;
using System.Collections.Concurrent;
namespace MrHassan.Copra
{
public class Pet
{
public enum PetType
{
Normal = 0,
Looter,
Stiger,
Attacker,
defender
}
public class PetInfo
{
public Entity Entity;
public PetType Type;
public GameState Owner;
}
#region Static Actions
private static TimerRule<GameState> PetsAction;
public static void CreateTimerFactories()
{
PetsAction = new TimerRule<GameState>(PetsActionCallback, 500);
}
private static void PetsActionCallback(GameState client, int time)
{
if (!client.Socket.Alive)
{
client.Pet.DisposeTimers();
return;
}
if (client.Entity == null)
return;
if (client.Map == null)
return;
if (client.Pet == null)
return;
if (client.Pet.Pets == null)
{
client.Pet.DisposeTimers();
return;
}
Time32 Now = new Time32(time);
var pets = client.Pet.Pets.Values;
foreach (var pet in pets)
{
if (pet != null)
{
#region Back To Owner
short distance = Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, client.Entity.X, client.Entity.Y);
if (distance >= 8)
{
ushort X = (ushort)(client.Entity.X + Kernel.Random.Next(2));
ushort Y = (ushort)(client.Entity.Y + Kernel.Random.Next(2));
if (!client.Map.SelectCoordonates(ref X, ref Y))
{
X = client.Entity.X;
Y = client.Entity.Y;
}
pet.Entity.X = X;
pet.Entity.Y = Y;
Network.GamePackets.Data data = new MrHassan.Network.GamePackets.Data(true);
data.ID = Network.GamePackets.Data.Jump;
data.dwParam = (uint)((Y << 16) | X);
data.wParam1 = X;
data.wParam2 = Y;
data.UID = pet.Entity.UID;
pet.Entity.MonsterInfo.SendScreen(data);
client.SendScreenSpawn(pet.Entity, true);
}
else if (distance > 4)
{
Enums.ConquerAngle facing = Kernel.GetAngle(pet.Entity.X, pet.Entity.Y, pet.Entity.Owner.Entity.X, pet.Entity.Owner.Entity.Y);
if (!pet.Entity.Move(facing))
{
facing = (Enums.ConquerAngle)Kernel.Random.Next(7);
if (pet.Entity.Move(facing))
{
pet.Entity.Facing = facing;
Network.GamePackets.GroundMovement move = new MrHassan.Network.GamePackets.GroundMovement(true);
move.Direction = facing;
move.UID = pet.Entity.UID;
move.GroundMovementType = Network.GamePackets.GroundMovement.Run;
pet.Entity.MonsterInfo.SendScreen(move);
}
}
else
{
pet.Entity.Facing = facing;
Network.GamePackets.GroundMovement move = new MrHassan.Network.GamePackets.GroundMovement(true);
move.Direction = facing;
move.UID = pet.Entity.UID;
move.GroundMovementType = Network.GamePackets.GroundMovement.Run;
pet.Entity.MonsterInfo.SendScreen(move);
}
client.SendScreenSpawn(pet.Entity, true);
}
#endregion
switch (pet.Type)
{
case PetType.Normal:
{
/* #region Normal Attack Guard
{
var monster = pet.Entity;
if (monster.MonsterInfo.InSight == 0)
{
if (client.Entity.AttackPacket != null)
{
if (client.Entity.AttackPacket.AttackType == Network.GamePackets.Attack.Magic)
{
if (client.Entity.AttackPacket.Decoded)
{
if (Database.SpellTable.SpellInformations.ContainsKey((ushort)client.Entity.AttackPacket.Damage))
{
var info = Database.SpellTable.SpellInformations[(ushort)client.Entity.AttackPacket.Damage].Values.ToArray()[client.Spells[(ushort)client.Entity.AttackPacket.Damage].Level];
if (info.CanKill)
{
monster.MonsterInfo.InSight = client.Entity.AttackPacket.Attacked;
}
}
}
}
else
{
monster.MonsterInfo.InSight = client.Entity.AttackPacket.Attacked;
}
}
}
else
{
if (monster.MonsterInfo.InSight > 400000 && monster.MonsterInfo.InSight < 600000 || monster.MonsterInfo.InSight > 800000 && monster.MonsterInfo.InSight != monster.UID)
{
Entity attacked = null;
if (client.Screen.TryGetValue(monster.MonsterInfo.InSight, out attacked))
{
if (Now > monster.AttackStamp.AddMilliseconds(monster.MonsterInfo.AttackSpeed))
{
monster.AttackStamp = Now;
if (attacked.Dead)
{
monster.MonsterInfo.InSight = 0;
}
else
new Game.Attacking.Handle(null, monster, attacked);
}
}
else
monster.MonsterInfo.InSight = 0;
}
}
}
#endregion*/
break;
}
case PetType.Stiger:
{
/* #region Stiger Guard
if (!client.Entity.ContainsFlag(Update.Flags.Stigma))
{
SpellUse suse = new SpellUse(true);
suse.Attacker = pet.Entity.UID;
suse.SpellID = 1095;
suse.SpellLevel = 4;
suse.X = client.Entity.X;
suse.Y = client.Entity.Y;
suse.AddTarget(client.Entity, 0, null);
client.Entity.AddFlag(Update.Flags.Stigma);
client.Entity.StigmaStamp = Time32.Now;
client.Entity.StigmaIncrease = 50;
client.Entity.StigmaTime = (byte)60;
if (client.Entity.EntityFlag == EntityFlag.Entity)
client.Entity.Owner.Send(Constants.Stigma(50, 60));
}
#endregion*/
break;
}
case PetType.Looter:
{
/* #region Shield Guard
if (!client.Entity.ContainsFlag(Update.Flags.MagicShield))
{
SpellUse suse = new SpellUse(true);
suse.Attacker = pet.Entity.UID;
suse.SpellID = 1090;
suse.SpellLevel = 4;
suse.X = client.Entity.X;
suse.Y = client.Entity.Y;
suse.AddTarget(client.Entity, 0, null);
client.Entity.AddFlag(Update.Flags.MagicShield);
client.Entity.ShieldStamp = Time32.Now;
client.Entity.ShieldIncrease = 1.1f;
client.Entity.ShieldTime = (byte)60;
if (client.Entity.EntityFlag == EntityFlag.Entity)
client.Entity.Owner.Send(Constants.Shield(50, 60));
}
#endregion*/
break;
}
case PetType.Attacker:
{
/* #region Attacker
foreach (var obj in client.Screen.Objects)
{
if (client.Entity.Dead)
return;
if (obj.MapObjType == MapObjectType.Monster)
{
var attacked = obj as Entity;
if (attacked.Companion || attacked.MonsterInfo.Guard)
continue;
// if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, attacked.X, attacked.Y) <= 15)
{
if (Now > pet.Entity.AttackStamp.AddMilliseconds(1000 - client.Entity.Agility))
{
pet.Entity.AttackStamp = Now;
if (!attacked.Dead)
new Game.Attacking.Handle(null, pet.Entity, attacked);
}
}
}
else if (obj.MapObjType == MapObjectType.Entity)
{
var attacked = obj as Entity;
if (attacked.Dead)
continue;
if (Game.Attacking.Handle.CanAttack(client.Entity, attacked, null, true))
{
// if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, attacked.X, attacked.Y) <= 15)
{
if (Now > pet.Entity.AttackStamp.AddMilliseconds(1000 - client.Entity.Agility))
{
pet.Entity.AttackStamp = Now;
if (!attacked.Dead)
new Game.Attacking.Handle(null, pet.Entity, attacked);
}
}
}
}
else if (obj.MapObjType == MapObjectType.SobNpc)
{
var attackedSobNpc = obj as SobNpcSpawn;
if (Game.Attacking.Handle.CanAttack(client.Entity, attackedSobNpc, null))
{
// if (Kernel.GetDistance(pet.Entity.X, pet.Entity.Y, attackedSobNpc.X, attackedSobNpc.Y) <= 15)
{
if (Now > pet.Entity.AttackStamp.AddMilliseconds(1000 - client.Entity.Agility))
{
pet.Entity.AttackStamp = Now;
SpellUse suse = new SpellUse(true);
Attack attack = new Attack(true);
attack.Effect1 = Attack.AttackEffects1.None;
uint damage = Game.Attacking.Calculate.Melee(client.Entity, attackedSobNpc, ref attack);
suse.Effect1 = attack.Effect1;
Game.Attacking.Handle.ReceiveAttack(pet.Entity, attackedSobNpc, attack, damage, null);
suse.Attacker = pet.Entity.UID;
suse.SpellID = pet.Entity.MonsterInfo.SpellID;
suse.X = attackedSobNpc.X;
suse.Y = attackedSobNpc.Y;
suse.AddTarget(attackedSobNpc, damage, attack);
pet.Entity.Owner.SendScreen(suse, true);
}
}
}
}
}
#endregion*/
break;
}
case PetType.defender:
{
/* #region defender
foreach (var obj in client.Screen.Objects)
{
if (obj.MapObjType == MapObjectType.Monster)
{
var attacked = obj as Entity;
if (attacked.MonsterInfo != null)
{
if (attacked.MonsterInfo.InSight == client.Entity.UID || attacked.MonsterInfo.InSight == pet.Entity.UID)
{
if (Now > pet.Entity.AttackStamp.AddMilliseconds(1000 - client.Entity.Agility))
{
pet.Entity.AttackStamp = Now;
if (!attacked.Dead)
new Game.Attacking.Handle(null, pet.Entity, attacked);
}
}
}
}
else if (obj.MapObjType == MapObjectType.Entity)
{
var attacked = obj as Entity;
if (attacked.AttackPacket != null)
{
if (attacked.AttackPacket.Attacked == client.Entity.UID || attacked.AttackPacket.Attacked == pet.Entity.UID)
{
if (Now > pet.Entity.AttackStamp.AddMilliseconds(1000 - client.Entity.Agility))
{
pet.Entity.AttackStamp = Now;
if (!attacked.Dead)
new Game.Attacking.Handle(null, pet.Entity, attacked);
}
}
}
}
}
#endregion*/
break;
}
}
}
else
break;
}
}
#endregion
#region Timers
private IDisposable[] TimerSubscriptions;
private object DisposalSyncRoot;
~Pet()
{
DisposeTimers();
Owner = null;
Pets = null;
}
private void DisposeTimers()
{
lock (DisposalSyncRoot)
{
if (TimerSubscriptions == null) return;
for (int i = 0; i < TimerSubscriptions.Length; i++)
{
if (TimerSubscriptions[i] != null)
{
TimerSubscriptions[i].Dispose();
TimerSubscriptions[i] = null;
}
}
}
}
#endregion
public uint MaxAllowed = 2;
public GameState Owner;
public SafeConcurrentDictionary<PetType, PetInfo> Pets;
public Pet(GameState client)
{
Owner = client;
Pets = new SafeConcurrentDictionary<PetType, PetInfo>();
TimerSubscriptions = new IDisposable[]
{
PetsAction.Add(client)
};
DisposalSyncRoot = new object();
}
public void AddPet(MonsterInformation Mob, PetType Type = PetType.Normal)
{
if (Pets.Count == MaxAllowed)
ClearAll();
if (Mob.Mesh == 847)
Type = PetType.Stiger;
if (Mob.Mesh == 850)
Type = PetType.Attacker;
if (Mob.Mesh == 848 || Mob.Mesh == 849)
Type = PetType.defender;
if (Mob.Mesh == 846)
Type = PetType.Looter;
if (Mob.SpellID == 0)
Mob.SpellID = 1002;
if (Type != PetType.Normal)
{
var mesh = Mob.Mesh;
var Name = Mob.Name;
MonsterInformation.MonsterInformations.TryGetValue(9003, out Mob);
Mob.Mesh = mesh;
Mob.Name = Name;
}
if (Pets.ContainsKey(Type))
{
Data data = new Data(true);
data.UID = Pets[Type].Entity.UID;
data.ID = Data.RemoveEntity;
Pets[Type].Entity.MonsterInfo.SendScreen(data);
Pets[Type].Entity = null;
Pets.Remove(Type);
}
PetInfo pet = new PetInfo();
pet.Type = Type;
pet.Owner = Owner;
pet.Entity = new Entity(EntityFlag.Monster, true);
pet.Entity.MonsterInfo = new MonsterInformation();
pet.Entity.Owner = Owner;
pet.Entity.MapObjType = MapObjectType.Monster;
pet.Entity.MonsterInfo = Mob.Copy();
pet.Entity.MonsterInfo.Owner = pet.Entity;
pet.Entity.Name = Mob.Name;
if (Type != PetType.Normal)
pet.Entity.Name = Mob.Name + "(" + Owner.Entity.Name + ")";
pet.Entity.MinAttack = Mob.MinAttack;
pet.Entity.MaxAttack = pet.Entity.MagicAttack = Math.Max(Mob.MinAttack, Mob.MaxAttack);
pet.Entity.Hitpoints = pet.Entity.MaxHitpoints = Mob.Hitpoints;
pet.Entity.Body = Mob.Mesh;
pet.Entity.Level = Mob.Level;
pet.Entity.UID = (uint)(Owner.Entity.UID - (200000 + Pets.Count));
pet.Entity.MapID = Owner.Map.ID;
pet.Entity.SendUpdates = true;
pet.Entity.X = Owner.Entity.X;
pet.Entity.Y = Owner.Entity.Y;
pet.Entity.pettype = Type;
Pets.Add(pet.Type, pet);
Owner.SendScreenSpawn(pet.Entity, true);
// pet.Entity.SendSpawn(Owner);
}
public void RemovePet(PetType Type)
{
if (Pets.Count == 0)
return;
if (Pets[Type] == null) return;
Data data = new Data(true);
data.UID = Pets[Type].Entity.UID;
data.ID = Data.RemoveEntity;
Pets[Type].Entity.MonsterInfo.SendScreen(data);
Pets.Remove(Type);
}
public void ClearAll()
{
if (Pets.Count > 0)
{
foreach (var pet in Pets.Values)
{
Data data = new Data(true);
data.UID = pet.Entity.UID;
data.ID = Data.RemoveEntity;
pet.Entity.MonsterInfo.SendScreen(data);
pet.Entity = null;
}
Pets.Clear();
}
}
}
}
public Languages Language = Languages.English;
public Copra.Pet Pet;
foreach (var clone in Entity.MyClones)
if (Entity.MyClones.Count > 0)
{
foreach (var item in Entity.MyClones.Values)
{
Data data = new Data(true);
data.UID = item.UID;
data.ID = Network.GamePackets.Data.RemoveEntity;
item.MonsterInfo.SendScreen(data);
}
Entity.MyClones.Clear();
}
public void Die(UInt32 killer)
foreach (var clone in MyClones)
if (MyClones.Count > 0)
{
foreach (var item in MyClones.Values)
{
Data data = new Data(true);
data.UID = item.UID;
data.ID = Network.GamePackets.Data.RemoveEntity;
item.MonsterInfo.SendScreen(data);
}
MyClones.Clear();
}
public void Die(Entity killer)
#region MyClones
#region MyClones
if (MyClones.Count > 0)
{
foreach (var item in MyClones.Values)
{
Data data = new Data(true);
data.UID = item.UID;
data.ID = Network.GamePackets.Data.RemoveEntity;
item.MonsterInfo.SendScreen(data);
}
MyClones.Clear();
}
#endregion
public void TeleportHouse(ushort MapID, ushort X, ushort Y)
if (MyClones.Count != 0)
{
foreach (var clone in MyClones)
clone.RemoveThat();
MyClones.Clear();
}
public void AdvancedTeleport(bool remove = false)
#region Teleport With Pet & Clones
#region Teleport With Pet & Clones
if (EntityFlag == EntityFlag.Entity)
{
if (MyClones.Count > 0)
{
foreach (var clone in MyClones.Values)
{
if (clone == null) continue;
if (remove)
{
Data data = new Data(true);
data.UID = clone.UID;
data.ID = Network.GamePackets.Data.RemoveEntity;
Owner.SendScreen(data);
Owner.RemoveScreenSpawn(clone, true);
}
else
{
clone.MapID = this.MapID;
clone.X = this.X;
clone.Y = this.Y;
Network.GamePackets.Data Data = new Network.GamePackets.Data(true);
Data.UID = clone.UID;
Data.ID = Network.GamePackets.Data.Teleport;
Data.dwParam = Database.MapsTable.MapInformations[MapID].BaseID;
Data.wParam1 = clone.X;
Data.wParam2 = clone.Y;
Owner.SendScreen(Data);
Owner.SendScreenSpawn(clone, true);
}
}
}
if (Owner.Pet != null)
{
if (Owner.Pet.Pets.Count > 0)
{
foreach (var pet in Owner.Pet.Pets.Values)
{
if (pet == null) continue;
if (pet.Entity == null) continue;
if (remove)
{
Data data = new Data(true);
data.UID = pet.Entity.UID;
data.ID = Network.GamePackets.Data.RemoveEntity;
Owner.SendScreen(data);
Owner.RemoveScreenSpawn(pet.Entity, true);
}
else
{
pet.Entity.MapID = this.MapID;
pet.Entity.X = this.X;
pet.Entity.Y = this.Y;
Owner.SendScreenSpawn(pet.Entity, true);
}
}
}
}
if (remove)
Owner.RemoveScreenSpawn(Owner.Entity, false);
}
#endregion Teleport With Pet & Clones
pet.Entity.pettype = Type;
#region shadowclone
#region shadowclone
case 12090:
{
attacker.attackpacket = null;
if (attacker.myclones.count > 0)
{
var clones = attacker.myclones.values.toarray();
for (int i = 0; i < clones.length; i++)
{
var item = clones[i];
if (item == null)
continue;
data data = new data(true);
data.uid = item.uid;
data.id = network.gamepackets.data.removeentity;
attacker.owner.sendscreen(data);
attacker.myclones[item.uid] = null;
}
attacker.myclones.clear();
}
else
{
if (canusespell(spell, attacker.owner))
{
preparespell(spell, attacker.owner);
spelluse spelluse = new spelluse(true);
spelluse.attacker = attacker.uid;
spelluse.spellid = spell.id;
spelluse.spelllevel = spell.level;
spelluse.x = x;
spelluse.y = y;
attacker.addclone(3);
if (spell.level >= 4)
attacker.addclone(10003);
foreach (var item in attacker.myclones.values)
spelluse.addtarget(item, 0, attack);
attacker.owner.sendscreen(spelluse, true);
}
}
break;
}
#endregion
public safedictionary<uint, entity> myclones = new safedictionary<uint, entity>();
public bool isclone = false;
public void addclone(ushort cloneid)
{
#region spawnpacket(10014)
var entity = new entity(entityflag.entity, true);
entity.monsterinfo = new monsterinformation();
monsterinformation.monsterinformations.trygetvalue(9003, out entity.monsterinfo);
entity.owner = owner;
entity.monsterinfo.owner = entity;
entity.isclone = true;
entity._name = "shadowclone";
entity.clan = name;
entity.spawnpacket = new byte[8 + _names + _name.length + 36];
array.copy(spawnpacket, entity.spawnpacket, entity.spawnpacket.length);
writestringlist(new list<string>() { "shadowclone", "", "", name, "" }, _names, entity.spawnpacket);
entity.mesh = mesh;
entity.hitpoints = 1;
entity.uid = owner.map.clonecounter.next;
entity.guildid = entity.guildrank = entity.action = 0;
entity.countryid = enums.countryid.default;
entity.statusflag = entity.statusflag2 = entity.statusflag3 = entity.statusflag4 = 0;
writer.write((uint)0, game.conquerstructures.equipment.steed, entity.spawnpacket);
writer.write((uint)0, game.conquerstructures.equipment.steedplus, entity.spawnpacket);
writer.write((uint)0, game.conquerstructures.equipment.steedcolor, entity.spawnpacket);
writer.write((uint)0, game.conquerstructures.equipment.mountarmor, entity.spawnpacket);
writer.write((uint)0, game.conquerstructures.equipment.wing, entity.spawnpacket);
writer.write((uint)0, game.conquerstructures.equipment.wingplus, entity.spawnpacket);
entity.flowerrank = 0;
entity.nobilityrank = conquerstructures.nobilityrank.serf;
entity.class = entity.firstrebornclass = entity.secondrebornclass = entity.jiangtalent = entity.subclassesactive = entity.reborn = entity.level = entity.serverid = 0;
writer.write((byte)2, 271, entity.spawnpacket);
writer.write(cloneid, 272, entity.spawnpacket);
entity.owneruid = uid;
entity.jiangactive = false;
writer.write((uint)0, 178, entity.spawnpacket);
writer.write((uint)0, 182, entity.spawnpacket);
writer.write((uint)0, 186, entity.spawnpacket);
writer.write((uint)0, _unionexploits, entity.spawnpacket);
writer.write((uint)0, _unionid, entity.spawnpacket);
writer.write((uint)0, _unionrank, entity.spawnpacket);
writer.write((uint)0, _uniontype, entity.spawnpacket);
writer.write((uint)0, _mytitle, entity.spawnpacket);
writer.write((uint)0, _mytitlescore, entity.spawnpacket);
writer.write((uint)0, _mywing, entity.spawnpacket);
entity.minattack = minattack;
entity.maxattack = entity.magicattack = math.max(minattack, maxattack);
entity.appearance = appearance;
entity.mapid = owner.map.id;
entity.sendupdates = true;
#endregion spawnpacket(10014)
#region pet(2035)
msgpetinfo pet = new msgpetinfo();
pet.uid = entity.uid;
pet.petid = cloneid;
pet.pettype = 2;
pet.mesh = mesh;
pet.attackrange = (byte)attackrange;
pet.x = x;
pet.y = y;
pet.name = "shadowclone";
owner.send(pet);
#endregion pet(2035)
myclones.add(entity.uid, entity);
owner.sendscreen(entity.spawnpacket, true);
owner.sendscreenspawn(entity, true);
#region data(10010)
data data = new data(true);
data.uid = entity.uid;
data.facing = entity.facing;
data.id = data.addentity;
data.wparam1 = entity.x;
data.wparam2 = entity.y;
owner.send(data);
#endregion data(10010)
}
public void reload(interfaces.ipacket spawnwith = null)
#region other pet & clones
#region other pet & clones
if (pclient.entity.myclones.count > 0)
{
foreach (var clone in pclient.entity.myclones.values)
{
if (clone == null) continue;
if (kernel.getdistance(clone.x, clone.y, owner.entity.x, owner.entity.y) <= 18 && !contains(clone.uid))
{
if (!clone.dead)
clone.sendspawn(owner);
}
}
}
if (pclient.pet.pets.count > 0)
{
foreach (var pet in pclient.pet.pets.values)
{
if (pet == null) continue;
if (pet.entity == null) continue;
if (kernel.getdistance(pet.entity.x, pet.entity.y, owner.entity.x, owner.entity.y) <= 18 && !contains(pet.entity.uid))
{
if (!pet.entity.dead)
pet.entity.sendspawn(owner);
}
}
}
#endregion
#region my pet & clones
#region my pet & clones
if (owner.entity.myclones.count > 0)
{
foreach (var clone in owner.entity.myclones.values)
{
if (clone == null) continue;
if (kernel.getdistance(clone.x, clone.y, owner.entity.x, owner.entity.y) <= 18 && !contains(clone.uid))
{
if (!clone.dead)
clone.sendspawn(owner);
}
}
}
if (owner.pet.pets.count > 0)
{
foreach (var pet in owner.pet.pets.values)
{
if (pet == null) continue;
if (pet.entity == null) continue;
if (kernel.getdistance(pet.entity.x, pet.entity.y, owner.entity.x, owner.entity.y) <= 18/* && !contains(pet.entity.uid)*/)
{
if (!pet.entity.dead)
owner.send(pet.entity.spawnpacket);
// pet.entity.sendspawn(owner, false);
}
}
}
#endregion
using system;
using system.collections.generic;
using system.linq;
using system.text;
using mrhassan.client;
using mrhassan.game;
using system.threading.generic;
using mrhassan.database;
using mrhassan.network.gamepackets;
using mrhassan.network;
using mrhassan.game.conquerstructures;
using system.collections.concurrent;
namespace mrhassan.copra
{
public class pet
{
public enum pettype
{
normal = 0,
looter,
stiger,
attacker,
defender
}
public class petinfo
{
public entity entity;
public pettype type;
public gamestate owner;
}
#region static actions
private static timerrule<gamestate> petsaction;
public static void createtimerfactories()
{
petsaction = new timerrule<gamestate>(petsactioncallback, 500);
}
private static void petsactioncallback(gamestate client, int time)
{
if (!client.socket.alive)
{
client.pet.disposetimers();
return;
}
if (client.entity == null)
return;
if (client.map == null)
return;
if (client.pet == null)
return;
if (client.pet.pets == null)
{
client.pet.disposetimers();
return;
}
time32 now = new time32(time);
var pets = client.pet.pets.values;
foreach (var pet in pets)
{
if (pet != null)
{
#region back to owner
short distance = kernel.getdistance(pet.entity.x, pet.entity.y, client.entity.x, client.entity.y);
if (distance >= 8)
{
ushort x = (ushort)(client.entity.x + kernel.random.next(2));
ushort y = (ushort)(client.entity.y + kernel.random.next(2));
if (!client.map.selectcoordonates(ref x, ref y))
{
x = client.entity.x;
y = client.entity.y;
}
pet.entity.x = x;
pet.entity.y = y;
network.gamepackets.data data = new mrhassan.network.gamepackets.data(true);
data.id = network.gamepackets.data.jump;
data.dwparam = (uint)((y << 16) | x);
data.wparam1 = x;
data.wparam2 = y;
data.uid = pet.entity.uid;
pet.entity.monsterinfo.sendscreen(data);
client.sendscreenspawn(pet.entity, true);
}
else if (distance > 4)
{
enums.conquerangle facing = kernel.getangle(pet.entity.x, pet.entity.y, pet.entity.owner.entity.x, pet.entity.owner.entity.y);
if (!pet.entity.move(facing))
{
facing = (enums.conquerangle)kernel.random.next(7);
if (pet.entity.move(facing))
{
pet.entity.facing = facing;
network.gamepackets.groundmovement move = new mrhassan.network.gamepackets.groundmovement(true);
move.direction = facing;
move.uid = pet.entity.uid;
move.groundmovementtype = network.gamepackets.groundmovement.run;
pet.entity.monsterinfo.sendscreen(move);
}
}
else
{
pet.entity.facing = facing;
network.gamepackets.groundmovement move = new mrhassan.network.gamepackets.groundmovement(true);
move.direction = facing;
move.uid = pet.entity.uid;
move.groundmovementtype = network.gamepackets.groundmovement.run;
pet.entity.monsterinfo.sendscreen(move);
}
client.sendscreenspawn(pet.entity, true);
}
#endregion
switch (pet.type)
{
case pettype.normal:
{
/* #region normal attack guard
{
var monster = pet.entity;
if (monster.monsterinfo.insight == 0)
{
if (client.entity.attackpacket != null)
{
if (client.entity.attackpacket.attacktype == network.gamepackets.attack.magic)
{
if (client.entity.attackpacket.decoded)
{
if (database.spelltable.spellinformations.containskey((ushort)client.entity.attackpacket.damage))
{
var info = database.spelltable.spellinformations[(ushort)client.entity.attackpacket.damage].values.toarray()[client.spells[(ushort)client.entity.attackpacket.damage].level];
if (info.cankill)
{
monster.monsterinfo.insight = client.entity.attackpacket.attacked;
}
}
}
}
else
{
monster.monsterinfo.insight = client.entity.attackpacket.attacked;
}
}
}
else
{
if (monster.monsterinfo.insight > 400000 && monster.monsterinfo.insight < 600000 || monster.monsterinfo.insight > 800000 && monster.monsterinfo.insight != monster.uid)
{
entity attacked = null;
if (client.screen.trygetvalue(monster.monsterinfo.insight, out attacked))
{
if (now > monster.attackstamp.addmilliseconds(monster.monsterinfo.attackspeed))
{
monster.attackstamp = now;
if (attacked.dead)
{
monster.monsterinfo.insight = 0;
}
else
new game.attacking.handle(null, monster, attacked);
}
}
else
monster.monsterinfo.insight = 0;
}
}
}
#endregion*/
break;
}
case pettype.stiger:
{
/* #region stiger guard
if (!client.entity.containsflag(update.flags.stigma))
{
spelluse suse = new spelluse(true);
suse.attacker = pet.entity.uid;
suse.spellid = 1095;
suse.spelllevel = 4;
suse.x = client.entity.x;
suse.y = client.entity.y;
suse.addtarget(client.entity, 0, null);
client.entity.addflag(update.flags.stigma);
client.entity.stigmastamp = time32.now;
client.entity.stigmaincrease = 50;
client.entity.stigmatime = (byte)60;
if (client.entity.entityflag == entityflag.entity)
client.entity.owner.send(constants.stigma(50, 60));
}
#endregion*/
break;
}
case pettype.looter:
{
/* #region shield guard
if (!client.entity.containsflag(update.flags.magicshield))
{
spelluse suse = new spelluse(true);
suse.attacker = pet.entity.uid;
suse.spellid = 1090;
suse.spelllevel = 4;
suse.x = client.entity.x;
suse.y = client.entity.y;
suse.addtarget(client.entity, 0, null);
client.entity.addflag(update.flags.magicshield);
client.entity.shieldstamp = time32.now;
client.entity.shieldincrease = 1.1f;
client.entity.shieldtime = (byte)60;
if (client.entity.entityflag == entityflag.entity)
client.entity.owner.send(constants.shield(50, 60));
}
#endregion*/
break;
}
case pettype.attacker:
{
/* #region attacker
foreach (var obj in client.screen.objects)
{
if (client.entity.dead)
return;
if (obj.mapobjtype == mapobjecttype.monster)
{
var attacked = obj as entity;
if (attacked.companion || attacked.monsterinfo.guard)
continue;
// if (kernel.getdistance(pet.entity.x, pet.entity.y, attacked.x, attacked.y) <= 15)
{
if (now > pet.entity.attackstamp.addmilliseconds(1000 - client.entity.agility))
{
pet.entity.attackstamp = now;
if (!attacked.dead)
new game.attacking.handle(null, pet.entity, attacked);
}
}
}
else if (obj.mapobjtype == mapobjecttype.entity)
{
var attacked = obj as entity;
if (attacked.dead)
continue;
if (game.attacking.handle.canattack(client.entity, attacked, null, true))
{
// if (kernel.getdistance(pet.entity.x, pet.entity.y, attacked.x, attacked.y) <= 15)
{
if (now > pet.entity.attackstamp.addmilliseconds(1000 - client.entity.agility))
{
pet.entity.attackstamp = now;
if (!attacked.dead)
new game.attacking.handle(null, pet.entity, attacked);
}
}
}
}
else if (obj.mapobjtype == mapobjecttype.sobnpc)
{
var attackedsobnpc = obj as sobnpcspawn;
if (game.attacking.handle.canattack(client.entity, attackedsobnpc, null))
{
// if (kernel.getdistance(pet.entity.x, pet.entity.y, attackedsobnpc.x, attackedsobnpc.y) <= 15)
{
if (now > pet.entity.attackstamp.addmilliseconds(1000 - client.entity.agility))
{
pet.entity.attackstamp = now;
spelluse suse = new spelluse(true);
attack attack = new attack(true);
attack.effect1 = attack.attackeffects1.none;
uint damage = game.attacking.calculate.melee(client.entity, attackedsobnpc, ref attack);
suse.effect1 = attack.effect1;
game.attacking.handle.receiveattack(pet.entity, attackedsobnpc, attack, damage, null);
suse.attacker = pet.entity.uid;
suse.spellid = pet.entity.monsterinfo.spellid;
suse.x = attackedsobnpc.x;
suse.y = attackedsobnpc.y;
suse.addtarget(attackedsobnpc, damage, attack);
pet.entity.owner.sendscreen(suse, true);
}
}
}
}
}
#endregion*/
break;
}
case pettype.defender:
{
/* #region defender
foreach (var obj in client.screen.objects)
{
if (obj.mapobjtype == mapobjecttype.monster)
{
var attacked = obj as entity;
if (attacked.monsterinfo != null)
{
if (attacked.monsterinfo.insight == client.entity.uid || attacked.monsterinfo.insight == pet.entity.uid)
{
if (now > pet.entity.attackstamp.addmilliseconds(1000 - client.entity.agility))
{
pet.entity.attackstamp = now;
if (!attacked.dead)
new game.attacking.handle(null, pet.entity, attacked);
}
}
}
}
else if (obj.mapobjtype == mapobjecttype.entity)
{
var attacked = obj as entity;
if (attacked.attackpacket != null)
{
if (attacked.attackpacket.attacked == client.entity.uid || attacked.attackpacket.attacked == pet.entity.uid)
{
if (now > pet.entity.attackstamp.addmilliseconds(1000 - client.entity.agility))
{
pet.entity.attackstamp = now;
if (!attacked.dead)
new game.attacking.handle(null, pet.entity, attacked);
}
}
}
}
}
#endregion*/
break;
}
}
}
else
break;
}
}
#endregion
#region timers
private idisposable[] timersubscriptions;
private object disposalsyncroot;
~pet()
{
disposetimers();
owner = null;
pets = null;
}
private void disposetimers()
{
lock (disposalsyncroot)
{
if (timersubscriptions == null) return;
for (int i = 0; i < timersubscriptions.length; i++)
{
if (timersubscriptions[i] != null)
{
timersubscriptions[i].dispose();
timersubscriptions[i] = null;
}
}
}
}
#endregion
public uint maxallowed = 2;
public gamestate owner;
public safeconcurrentdictionary<pettype, petinfo> pets;
public pet(gamestate client)
{
owner = client;
pets = new safeconcurrentdictionary<pettype, petinfo>();
timersubscriptions = new idisposable[]
{
petsaction.add(client)
};
disposalsyncroot = new object();
}
public void addpet(monsterinformation mob, pettype type = pettype.normal)
{
if (pets.count == maxallowed)
clearall();
if (mob.mesh == 847)
type = pettype.stiger;
if (mob.mesh == 850)
type = pettype.attacker;
if (mob.mesh == 848 || mob.mesh == 849)
type = pettype.defender;
if (mob.mesh == 846)
type = pettype.looter;
if (mob.spellid == 0)
mob.spellid = 1002;
if (type != pettype.normal)
{
var mesh = mob.mesh;
var name = mob.name;
monsterinformation.monsterinformations.trygetvalue(9003, out mob);
mob.mesh = mesh;
mob.name = name;
}
if (pets.containskey(type))
{
data data = new data(true);
data.uid = pets[type].entity.uid;
data.id = data.removeentity;
pets[type].entity.monsterinfo.sendscreen(data);
pets[type].entity = null;
pets.remove(type);
}
petinfo pet = new petinfo();
pet.type = type;
pet.owner = owner;
pet.entity = new entity(entityflag.monster, true);
pet.entity.monsterinfo = new monsterinformation();
pet.entity.owner = owner;
pet.entity.mapobjtype = mapobjecttype.monster;
pet.entity.monsterinfo = mob.copy();
pet.entity.monsterinfo.owner = pet.entity;
pet.entity.name = mob.name;
if (type != pettype.normal)
pet.entity.name = mob.name + "(" + owner.entity.name + ")";
pet.entity.minattack = mob.minattack;
pet.entity.maxattack = pet.entity.magicattack = math.max(mob.minattack, mob.maxattack);
pet.entity.hitpoints = pet.entity.maxhitpoints = mob.hitpoints;
pet.entity.body = mob.mesh;
pet.entity.level = mob.level;
pet.entity.uid = (uint)(owner.entity.uid - (200000 + pets.count));
pet.entity.mapid = owner.map.id;
pet.entity.sendupdates = true;
pet.entity.x = owner.entity.x;
pet.entity.y = owner.entity.y;
pet.entity.pettype = type;
pets.add(pet.type, pet);
owner.sendscreenspawn(pet.entity, true);
// pet.entity.sendspawn(owner);
}
public void removepet(pettype type)
{
if (pets.count == 0)
return;
if (pets[type] == null) return;
data data = new data(true);
data.uid = pets[type].entity.uid;
data.id = data.removeentity;
pets[type].entity.monsterinfo.sendscreen(data);
pets.remove(type);
}
public void clearall()
{
if (pets.count > 0)
{
foreach (var pet in pets.values)
{
data data = new data(true);
data.uid = pet.entity.uid;
data.id = data.removeentity;
pet.entity.monsterinfo.sendscreen(data);
pet.entity = null;
}
pets.clear();
}
}
}
}
public languages language = languages.english;
public copra.pet pet;
foreach (var clone in entity.myclones)
if (entity.myclones.count > 0)
{
foreach (var item in entity.myclones.values)
{
data data = new data(true);
data.uid = item.uid;
data.id = network.gamepackets.data.removeentity;
item.monsterinfo.sendscreen(data);
}
entity.myclones.clear();
}
public void die(uint32 killer)
foreach (var clone in myclones)
if (myclones.count > 0)
{
foreach (var item in myclones.values)
{
data data = new data(true);
data.uid = item.uid;
data.id = network.gamepackets.data.removeentity;
item.monsterinfo.sendscreen(data);
}
myclones.clear();
}
public void die(entity killer)
#region myclones
#region myclones
if (myclones.count > 0)
{
foreach (var item in myclones.values)
{
data data = new data(true);
data.uid = item.uid;
data.id = network.gamepackets.data.removeentity;
item.monsterinfo.sendscreen(data);
}
myclones.clear();
}
#endregion
public void teleporthouse(ushort mapid, ushort x, ushort y)
if (myclones.count != 0)
{
foreach (var clone in myclones)
clone.removethat();
myclones.clear();
}
public void advancedteleport(bool remove = false)
#region teleport with pet & clones
#region teleport with pet & clones
if (entityflag == entityflag.entity)
{
if (myclones.count > 0)
{
foreach (var clone in myclones.values)
{
if (clone == null) continue;
if (remove)
{
data data = new data(true);
data.uid = clone.uid;
data.id = network.gamepackets.data.removeentity;
owner.sendscreen(data);
owner.removescreenspawn(clone, true);
}
else
{
clone.mapid = this.mapid;
clone.x = this.x;
clone.y = this.y;
network.gamepackets.data data = new network.gamepackets.data(true);
data.uid = clone.uid;
data.id = network.gamepackets.data.teleport;
data.dwparam = database.mapstable.mapinformations[mapid].baseid;
data.wparam1 = clone.x;
data.wparam2 = clone.y;
owner.sendscreen(data);
owner.sendscreenspawn(clone, true);
}
}
}
if (owner.pet != null)
{
if (owner.pet.pets.count > 0)
{
foreach (var pet in owner.pet.pets.values)
{
if (pet == null) continue;
if (pet.entity == null) continue;
if (remove)
{
data data = new data(true);
data.uid = pet.entity.uid;
data.id = network.gamepackets.data.removeentity;
owner.sendscreen(data);
owner.removescreenspawn(pet.entity, true);
}
else
{
pet.entity.mapid = this.mapid;
pet.entity.x = this.x;
pet.entity.y = this.y;
owner.sendscreenspawn(pet.entity, true);
}
}
}
}
if (remove)
owner.removescreenspawn(owner.entity, false);
}
#endregion teleport with pet & clones
pet.entity.pettype = type;
الذين يشاهدون محتوى الموضوع الآن : 1 ( الأعضاء 0 والزوار 1) | |
|
الموضوع | كاتب الموضوع | المنتدى | مشاركات | آخر مشاركة |
مشكلة بخصوص اسكل ShadowClone | OmarMimi5095 | مشكلات السيرفيرات كونكر الشخصيه | 1 | 2021-08-05 04:23 AM |
بخصوص اسكلة ThunedCloud | Mostafa Shalby | مشكلات السيرفيرات كونكر الشخصيه | 13 | 2019-10-29 06:45 PM |
حل مشكله اسكلة ShadowClone | Tefa | تطوير سيرفرات كونكر | 2 | 2019-10-24 02:55 PM |
مشكله بخصوص ShadowClone | uncelsam | مشكلات السيرفيرات كونكر الشخصيه | 2 | 2019-10-23 08:06 PM |
مشكلة فى اسكلة ShadowClone | osama | مشكلات السيرفيرات كونكر الشخصيه | 2 | 2019-08-05 09:10 AM |