internal void SendLogoutPackets(Client client) { CancelTrade ct = new CancelTrade(); ct.FromID = (uint)client.ZonePlayer.ID; ct.Action = 7; // TODO: figure out wtf 7 is and constant-ize it (looks like a group action of "update") EQApplicationPacket<CancelTrade> ctPack = new EQApplicationPacket<CancelTrade>(AppOpCode.CancelTrade, ct); client.SendApplicationPacket(ctPack); EQRawApplicationPacket plrPack = new EQRawApplicationPacket(AppOpCode.PreLogoutReply, client.IPEndPoint, null); client.SendApplicationPacket(plrPack); }
void Mob_SpellCastBegun(object sender, BeginCastEventArgs bce) { Mob m = sender as Mob; BeginCast bc = new BeginCast() { CasterId = (ushort)m.ID, SpellId = (ushort)bce.SpellId, CastTime = bce.CastTime }; EQApplicationPacket<BeginCast> bcPacket = new EQApplicationPacket<BeginCast>(AppOpCode.BeginCast, bc); _zoneSvr.QueuePacketToNearbyClients(m, bcPacket, 200.0f, false); }
void Mob_PositionUpdate(object sender, PosUpdateEventArgs e) { Mob mob = sender as Mob; PlayerPositionUpdateServer ppus; if (e.UseDelta) { ppus = mob.GetSpawnUpdate(); EQApplicationPacket<PlayerPositionUpdateServer> ppusPack = new EQApplicationPacket<PlayerPositionUpdateServer>(AppOpCode.ClientUpdate, ppus); _zoneSvr.QueuePacketToNearbyClients(mob, ppusPack, 800, true); } else { ppus = mob.GetSpawnUpdateNoDelta(); EQApplicationPacket<PlayerPositionUpdateServer> ppusPack = new EQApplicationPacket<PlayerPositionUpdateServer>(AppOpCode.ClientUpdate, ppus); if (e.OnlyNearby) _zoneSvr.QueuePacketToNearbyClients(mob, ppusPack, 800, true); else _zoneSvr.QueuePacketToClients(mob, ppusPack, true); } }
void Mob_PlayAnimation(object sender, AnimationEventArgs ae) { Mob mob = sender as Mob; Animation anim = new Animation() { Action = 10, SpawnID = (ushort)mob.ID, Value = (byte)ae.Anim }; EQApplicationPacket<Animation> animPack = new EQApplicationPacket<Animation>(AppOpCode.Animation, anim); _zoneSvr.QueuePacketToNearbyClients(mob, animPack, 200.0f, false, true); }
/// <summary>Called when the client is allowed to zone. Handles all which must happen when a client zones out.</summary> internal void ZoneClient(ZoneChange zc, Zone targetZone, float destX, float destY, float destZ, float destH, byte ignoreRestrictions, Client client) { this.SendLogoutPackets(client); _mobMgr.RemoveFromAllHateLists(client.ZonePlayer); // TODO: clear aggro for pet, if present _log.DebugFormat("{0} is ATTEMPTING to zone to {1} ({2}) {3}x {4}y {5}z", client.ZonePlayer.Name, targetZone.ShortName, targetZone.ZoneID, destX, destY, destZ); ZoneChange zcOut = new ZoneChange(); if (targetZone.ZoneID == this.Zone.ZoneID) { // Zoning to same zone (maybe a bind point, etc.) zcOut.ZoneID = this.Zone.ZoneID; zcOut.Success = (int)ZoneError.Success; client.ZonePlayer.X = destX; client.ZonePlayer.Y = destY; client.ZonePlayer.Z = destZ; client.ZonePlayer.Heading = destH; _log.InfoFormat("{0} is zoning to same zone {1}x {2}y {3}z (no error)", client.ZonePlayer.Name, destX, destY, destZ); AddClientAuth(client.IPEndPoint.Address.ToString(), true); // add to expected clients list } else { // Send a ZTZ to World ZoneToZone ztz = new ZoneToZone(); ztz.CharName = client.ZonePlayer.Name; ztz.CharId = client.ZonePlayer.ID; ztz.ClientIp = client.IPEndPoint.Address.ToString(); ztz.CurrentZoneId = this.Zone.ZoneID; ztz.RequestedZoneId = targetZone.ZoneID; ztz.AccountStatus = client.ZonePlayer.AccountStatus; ztz.IgnoreRestrictions = ignoreRestrictions; int ztzResult = WorldSvc.ZoneToZone(ztz); if (ztzResult > 0) { // problems zcOut.Success = (int)ZoneError.NotReady; client.ZonePlayer.ZoneId = this.Zone.ZoneID; // client isn't zoning after all, so set the id back to this zone _log.InfoFormat("{0} is zoning to same zone {1}x {2}y {3}z due to error code {4} when asking world to zone", client.ZonePlayer.Name, destX, destY, destZ, ztzResult); client.ZonePlayer.MsgMgr.SendSpecialMessage(MessageType.Default, string.Format("There was a problem zoning. Code {0}.", ztzResult)); } else { zcOut.Init(); Buffer.BlockCopy(Encoding.ASCII.GetBytes(client.ZonePlayer.Name), 0, zcOut.CharName, 0, client.ZonePlayer.Name.Length); zcOut.ZoneID = targetZone.ZoneID; zcOut.Success = (int)ZoneError.Success; client.ZonePlayer.X = destX; client.ZonePlayer.Y = destY; client.ZonePlayer.Z = destZ; client.ZonePlayer.Heading = destH; client.ZonePlayer.ZoneId = targetZone.ZoneID; _log.InfoFormat("{0} is zoning to {1} ({2}) {3}x {4}y {5}z", client.ZonePlayer.Name, targetZone.ShortName, targetZone.ZoneID, destX, destY, destZ); // TODO: for ignoreRestrictions of 3, get safe coords for target zone } } client.ZonePlayer.ZoneMode = ZoneMode.Unsolicited; // reset the zoneMode client.ZonePlayer.Save(); // this forced save ensures the correct zone info is available to world when zoning the client EQApplicationPacket<ZoneChange> zcPack = new EQApplicationPacket<ZoneChange>(AppOpCode.ZoneChange, zcOut); client.SendApplicationPacket(zcPack); }
void InvMgr_ItemChargeUsed(object sender, ItemChargeUseEventArgs e) { MoveItem mi = new MoveItem() { FromSlot = e.SlotID, NumberInStack = 0xFFFFFFFF, ToSlot = 0xFFFFFFFF }; EQApplicationPacket<MoveItem> miPack = new EQApplicationPacket<MoveItem>(AppOpCode.DeleteCharge, mi); for (int i = 0; i < e.Charges; i++) this.Client.SendApplicationPacket(miPack); }
internal void SetSkillLevel(Skill skill, uint level) { if (skill > Skill.Highest) throw new ArgumentException("Skill is beyond the range of legal skill values.", "skill"); _pp.Skills[(uint)skill] = level; SkillUpdate su = new SkillUpdate() { SkillId = (uint)skill, SkillValue = level }; EQApplicationPacket<SkillUpdate> suPack = new EQApplicationPacket<SkillUpdate>(AppOpCode.SkillUpdate, su); this.Client.SendApplicationPacket(suPack); }
private void PlayerDeath(ZonePlayer zp, Mob lastAttacker, uint spellId, byte damageType, uint damage) { _log.DebugFormat("{0} bought the farm. Fatal blow dealt by {1} with {2} damage, skill {3}, spell {4}.", zp.Name, lastAttacker.Name, damage, damageType, spellId); if (zp.IsDePopped) { _log.WarnFormat("{0} is trying to die more than once or something... is already depopped!", zp.Name); return; } _zoneSvr.SendLogoutPackets(zp.Client); // Make the become corpse packet and queue to player before Death opCode packet BecomeCorpse bc = new BecomeCorpse() { SpawnId = (uint)zp.ID, X = zp.X, Y = zp.Y, Z = zp.Z }; EQApplicationPacket<BecomeCorpse> bcPack = new EQApplicationPacket<BecomeCorpse>(AppOpCode.BecomeCorpse, bc); _zoneSvr.QueuePacketToClient(zp.Client, bcPack, true, ZoneConnectionState.All); Death d = new Death() { SpawnId = (uint)zp.ID, KillerId = lastAttacker == null ? 0u : (uint)lastAttacker.ID, CorpseId = (uint)zp.ID, BindToZoneId = zp.PlayerProfile.Binds[0].ZoneId, SpellId = spellId == 0u ? 0xFFFFFFFF : spellId, AttackSkillId = spellId != 0u ? (uint)0xe7 : damageType, Damage = damage }; EQApplicationPacket<Death> dPack = new EQApplicationPacket<Death>(AppOpCode.Death, d); _zoneSvr.QueuePacketToClients(lastAttacker, dPack, false); RemoveFromAllTargets(zp); // orig emu removed self from its own hate list... don't understand why you'd do that, so skipping if (!zp.IsGM) { // GM's don't get penalized from dieing... muwhahaha // Figure out how much xp we lose, if any int xpLoss = 0; if (zp.Level >= WorldServer.ServerConfig.LevelDeathDoesXPLoss) // TODO: don't lose xp when we have become an NPC? xpLoss = (int)(zp.XP * WorldServer.ServerConfig.XPLossModifier); if (lastAttacker is ZonePlayer) // TODO: also check if the attacker is a pet owned by a player (no xp loss in that case) xpLoss = 0; // Don't lose xp when dueling _log.DebugFormat("{0} is losing {1} xp due to his ass died.", zp.Name, xpLoss); zp.XP -= xpLoss; // TODO: fade buffs (ALL - good and bad) // TODO: unmem spells (don't send packets) PlayerCorpse pc = new PlayerCorpse(zp, xpLoss, _zoneSvr.HasGraveyard()); AddCorpse(pc); _zoneSvr.QueuePacketToClients(zp, bcPack, true); // send the become corpse packet to all players in the zone } else { // TODO: fade just detrimental buffs } // Send player to bind point _zoneSvr.MovePlayer(zp, zp.PlayerProfile.Binds[0].ZoneId, 0, zp.PlayerProfile.Binds[0].X, zp.PlayerProfile.Binds[0].Y, zp.PlayerProfile.Binds[0].Z, zp.PlayerProfile.Binds[0].Heading, ZoneMode.ZoneToBindPoint); }
internal void SendLootRequestErrorPacket(Client client, byte response) { MoneyOnCorpse moc = new MoneyOnCorpse() { Response = response }; EQApplicationPacket<MoneyOnCorpse> mocPack = new EQApplicationPacket<MoneyOnCorpse>(AppOpCode.MoneyOnCorpse, moc); client.SendApplicationPacket(mocPack); }
private void SendZoneCancel(ZoneChange zc, Client client) { // send client right back to where they were - TODO: could this be improved? Buffer.BlockCopy(Encoding.ASCII.GetBytes(client.ZonePlayer.Name), 0, zc.CharName, 0, client.ZonePlayer.Name.Length); zc.ZoneID = (ushort)this.Zone.ZoneID; zc.Success = 1; EQApplicationPacket<ZoneChange> zcPack = new EQApplicationPacket<ZoneChange>(AppOpCode.ZoneChange, zc); client.SendApplicationPacket(zcPack); client.ZonePlayer.ZoneMode = ZoneMode.Unsolicited; }
private void SendZoneError(ZoneChange zc, ZoneError errCode, Client client) { _log.InfoFormat("Zone {0} is not available for {1} because it wasn't found, insufficient flags, insufficient level or locked zone", zc.ZoneID, client.ZonePlayer.Name); ZoneChange zcOut = new ZoneChange(client.ZonePlayer.Name); zcOut.ZoneID = zc.ZoneID; zcOut.Success = (int)errCode; EQApplicationPacket<ZoneChange> zcPack = new EQApplicationPacket<ZoneChange>(AppOpCode.ZoneChange, zcOut); client.SendApplicationPacket(zcPack); }
internal void SendStancePacket(SpawnAppearanceType appearType, Mob mob, short stanceValue, bool wholeZone, bool ignoreSelf, Client target) { SpawnAppearance sa = new SpawnAppearance((ushort)mob.ID, (ushort)appearType, (uint)stanceValue); EQApplicationPacket<SpawnAppearance> saPack = new EQApplicationPacket<SpawnAppearance>(AppOpCode.SpawnAppearance, sa); if (wholeZone) this.QueuePacketToClients(mob, saPack, ignoreSelf); else if (target != null) QueuePacketToClient(target, saPack, false, ZoneConnectionState.Connected); else if (mob is ZonePlayer) QueuePacketToClient(((ZonePlayer)mob).Client, saPack, false, ZoneConnectionState.Connected); }
private void SpawnQueueTimerCallback(object state) { EQRawApplicationPacket packet = null; Internals.Packets.Spawn spawn; while (_spawnQueue.Count > 0) { try { lock (((ICollection)_spawnQueue).SyncRoot) { spawn = _spawnQueue.Dequeue(); } // send the packet packet = new EQApplicationPacket<Internals.Packets.Spawn>(AppOpCode.NewSpawn, spawn); QueuePacketToClients(null, packet, true); } catch (Exception e) { _log.Error("SpawnQueueTimerCallback error", e); } } }
private void AddNpc(NpcMob npcMob, bool sendSpawnPacket, bool dontQueue) { // TODO: try to see if we can get away with only one list for mobs & npcs... npcs are in the mob list, so hey, it might work //_npcMobs.Add(npcMob.NpcID, npcMob); // Added by id of the npc db entity AddMob(npcMob); if (sendSpawnPacket) { if (dontQueue) { EQApplicationPacket<Internals.Packets.Spawn> spawnPack = new EQApplicationPacket<Internals.Packets.Spawn>(AppOpCode.NewSpawn, npcMob.GetSpawn()); QueuePacketToClients(null, spawnPack, true); // TODO: raise spawn event } else if (_clients.Count > 0) // no clients, no send anything { lock (((ICollection)_spawnQueue).SyncRoot) { _spawnQueue.Enqueue(npcMob.GetSpawn()); } } // TODO: raise spawn event - nah, better place is where it actually spawns, yea? } }
void Mob_WearChanged(object sender, WearChangeEventArgs wce) { //_log.DebugFormat("Sending wear change for {0} ({1})", sender, wce.WearChange); EQApplicationPacket<WearChange> wcPack = new EQApplicationPacket<WearChange>(AppOpCode.WearChange, wce.WearChange); _zoneSvr.QueuePacketToClients(sender as Mob, wcPack, true); }
override public MerchantManager GetMerchantData(NPCSpawnList npcsl) { List <EQApplicationPacket> PacketList = Packets.PacketList; UInt32 OP_ShopRequest = OpManager.OpCodeNameToNumber("OP_ShopRequest"); UInt32 OP_ShopEnd = OpManager.OpCodeNameToNumber("OP_ShopEnd"); UInt32 OP_ItemPacket = OpManager.OpCodeNameToNumber("OP_ItemPacket"); MerchantManager mm = new MerchantManager(); for (int i = 0; i < PacketList.Count; ++i) { EQApplicationPacket p = PacketList[i]; if ((p.Direction == PacketDirection.ServerToClient) && (p.OpCode == OP_ShopRequest)) { ByteStream Buffer = new ByteStream(p.Buffer); UInt32 MerchantSpawnID = Buffer.ReadUInt32(); NPCSpawn npc = npcsl.GetNPC(MerchantSpawnID); UInt32 NPCTypeID; if (npc != null) { NPCTypeID = npc.NPCTypeID; } else { NPCTypeID = 0; } mm.AddMerchant(MerchantSpawnID); for (int j = i + 1; j < PacketList.Count; ++j) { p = PacketList[j]; if (p.OpCode == OP_ShopEnd) { break; } if (p.OpCode == OP_ItemPacket) { Buffer = new ByteStream(p.Buffer); UInt32 StackSize = Buffer.ReadUInt32(); Buffer.SkipBytes(4); UInt32 Slot = Buffer.ReadUInt32(); UInt32 MerchantSlot = Buffer.ReadUInt32(); UInt32 Price = Buffer.ReadUInt32(); Int32 Quantity = Buffer.ReadInt32(); Buffer.SetPosition(68); // Point to item name string ItemName = Buffer.ReadString(true); string Lore = Buffer.ReadString(true); string IDFile = Buffer.ReadString(true); UInt32 ItemID = Buffer.ReadUInt32(); //if (Quantity == -1) mm.AddMerchantItem(MerchantSpawnID, ItemID, ItemName, MerchantSlot, Quantity); } } } } return(mm); }
private void NpcDeath(NpcMob npc, Mob lastAttacker, uint spellId, byte damageType, uint damage) { RemoveFromAllTargets(npc); // Remove NPC from any entity's target & hate lists // Send Death Packet Death d = new Death() { SpawnId = (uint)npc.ID, KillerId = lastAttacker == null ? 0u : (uint)lastAttacker.ID, BindToZoneId = 0u, SpellId = spellId == 0u ? 0xFFFFFFFF : spellId, AttackSkillId = damageType, Damage = damage }; EQApplicationPacket<Death> dPack = new EQApplicationPacket<Death>(AppOpCode.Death, d); _zoneSvr.QueuePacketToClients(lastAttacker, dPack, false); // TODO: this should be cool with a null lastAttacker, right? // TODO: something about respawn? Mob killer = npc.HateMgr.GetTopHated(); Mob xpMob = npc.HateMgr.GetTopDamager(); // Give xp out if (xpMob == null) xpMob = killer; if (xpMob == null) xpMob = lastAttacker; // TODO: if xpMob is pet, get the owner ZonePlayer xpClient = xpMob as ZonePlayer; if (xpClient != null) { // TODO: handle raid split, LDON adventure crap, etc. float groupBonus = 1.0f; if (xpClient.IsGrouped) { // TODO: handle group split // TODO: add group xp bonus } else { ConLevel conLvl = Mob.GetConsiderDificulty(xpClient.Level, npc.Level); if (conLvl != ConLevel.Green) { // TODO: figure high con bonus, if any int baseXp = (int)(npc.Level * npc.Level * groupBonus * _zoneSvr.Zone.XPMultiplier); xpClient.GiveXP((int)(npc.Level * npc.Level * 75 * _zoneSvr.Zone.XPMultiplier), conLvl); } } // TODO: raise death merit event? } // TODO: faction hits // Make a corpse and add to the manager if (npc.IsLootable) { // TODO: add additional checks for stuff like a guard killing the mob, etc. Corpse c = new Corpse(npc, npc.LootItems); AddCorpse(c); // TODO: if killer is a pet, get the owner if (xpClient != null) c.AllowLooter(killer as ZonePlayer); } // TODO: raise script event _log.DebugFormat("NPC {0} has died", npc.ID); }
internal void SendMessageID(uint type, MessageStrings msgStr) { // TODO: add message filtering once filters are in SimpleMessage sm = new SimpleMessage() { Color = type, StringID = (uint)msgStr }; EQApplicationPacket<SimpleMessage> smPack = new EQApplicationPacket<SimpleMessage>(AppOpCode.SimpleMessage, sm); _zp.Client.SendApplicationPacket(smPack, true); }
void ZonePlayer_LevelGained(object sender, EventArgs e) { ZonePlayer zp = sender as ZonePlayer; LevelAppearance la = new LevelAppearance() { SpawnID = (uint)zp.ID, Parm1 = 0x4d, Parm2 = 0x4d + 1, Parm3 = 0x4d + 2, Parm4 = 0x4d + 3, Parm5 = 0x4d + 4, Value1a = 1, Value2a = 2, Value3a = 1, Value3b = 1, Value4a = 1, Value4b = 1, Value5a = 2 }; EQApplicationPacket<LevelAppearance> laPack = new EQApplicationPacket<LevelAppearance>(AppOpCode.LevelAppearance, la); _zoneSvr.QueuePacketToNearbyClients(zp, laPack, 200.0f, false, true); _zoneSvr.UpdateWorldWho(zp.Client); _log.InfoFormat("{0} has dinged to level {1}", zp.Name, zp.Level); }
void Mob_Damaged(object sender, DamageEventArgs de) { Mob sourceMob = this[de.SourceId]; // This safely gets a null if sourceId == 0 Mob targetMob = sender as Mob; if (targetMob.Dead) { if (targetMob is NpcMob) // TODO: will want to handle pets here as well NpcDeath(targetMob as NpcMob, sourceMob, de.SpellId, de.Type, de.Damage); else if (targetMob is ZonePlayer) PlayerDeath(targetMob as ZonePlayer, sourceMob, de.SpellId, de.Type, de.Damage); return; } CombatDamage cd = new CombatDamage() { TargetId = (ushort)targetMob.ID, SourceId = de.SourceId, DamageType = de.Type, Damage = de.Damage, SpellId = de.SpellId }; EQApplicationPacket<CombatDamage> cdPack = new EQApplicationPacket<CombatDamage>(AppOpCode.Damage, cd); // TODO: choose right filter and then add to packet queue methods // Send to attacker if it's a player TODO: verify this sends spell dmg if (de.SourceId != 0 && sourceMob is ZonePlayer) _zoneSvr.QueuePacketToClient(((ZonePlayer)sourceMob).Client, cdPack, true, ZoneConnectionState.Connected); // Send to nearby players _zoneSvr.QueuePacketToNearbyClients(targetMob, cdPack, 200.0f, true, true, new int[] { de.SourceId }); // Send to defender if it's a player if (targetMob is ZonePlayer) { //_log.DebugFormat("Telling {0} they were damaged for {1} points.", targetMob.Name, de.Damage); _zoneSvr.QueuePacketToClient(((ZonePlayer)targetMob).Client, cdPack, true, ZoneConnectionState.Connected); } }
protected void OnManaStaChanged(EventArgs e) { if (!(this.ConnectionState == ZoneConnectionState.Connected) || this.IsCasting) { if (_lastReportedMana != this.Mana || _lastReportedEnd != this.Endurance) { ManaStaChange msc = new ManaStaChange() { NewEndurance = this.Endurance, NewMana = (uint)this.Mana, SpellId = 0 }; EQApplicationPacket<ManaStaChange> mscPack = new EQApplicationPacket<ManaStaChange>(AppOpCode.ManaChange, msc); this.Client.SendApplicationPacket(mscPack); _lastReportedEnd = this.Endurance; _lastReportedMana = (uint)this.Mana; } } }
void Mob_HpUpdated(object sender, EventArgs e) { Mob mob = sender as Mob; HPUpdateRatio hpRatio = mob.GetHPUpdateRatio(); HPUpdateExact hpExact = mob.GetHPUpdateExact(); // TODO: adjust for itembonuses EQApplicationPacket<HPUpdateRatio> hpRatioPacket = new EQApplicationPacket<HPUpdateRatio>(AppOpCode.MobHealth, hpRatio); EQApplicationPacket<HPUpdateExact> hpExactPacket = new EQApplicationPacket<HPUpdateExact>(AppOpCode.HPUpdate, hpExact); // Send to those who have us targeted _zoneSvr.QueuePacketToClientsByTarget(mob, hpRatioPacket, true, false); // TODO: queue to groups for npc health - whatever that means // TODO: once groups are in, send to group // TODO: send to raid // TODO: once pets are in, send to master/pet ZonePlayer zp = sender as ZonePlayer; if (zp != null) { _zoneSvr.QueuePacketToClient(zp.Client, hpExactPacket, true, ZoneConnectionState.All); // Send exact hps to self //_log.DebugFormat("Sent exact HPs to self - max:{0} cur:{1}", hpExact.MaxHP, hpExact.CurrentHP); } // TODO: HP Script Event }
void InvMgr_ItemMoved(object sender, ItemMoveEventArgs e) { // TODO: when attuneable items are in, check for attuneable and set invItem attuned // TODO: old emu set the equipment material here but I don't see that ever being used if (e.ToSlotID <= (uint)InventorySlot.EquipSlotsEnd) TriggerWearChange(InventoryManager.GetEquipableType((InventorySlot)e.ToSlotID)); if (e.FromSlotID <= (uint)InventorySlot.EquipSlotsEnd) TriggerWearChange(InventoryManager.GetEquipableType((InventorySlot)e.FromSlotID)); if (e.NotifyClient) { MoveItem mi = new MoveItem() { FromSlot = e.FromSlotID, NumberInStack = e.Quantity, ToSlot = e.ToSlotID }; EQApplicationPacket<MoveItem> miPack = null; if (e.Quantity > 0) { // Moving from a stack? mi.NumberInStack = 0xFFFFFFFF; if (e.ToSlotID == 0xFFFFFFFF) miPack = new EQApplicationPacket<MoveItem>(AppOpCode.DeleteItem, mi); else miPack = new EQApplicationPacket<MoveItem>(AppOpCode.MoveItem, mi); // TODO: this right? for (int i = 0; i < e.Quantity; i++) this.Client.SendApplicationPacket(miPack); } else { mi.NumberInStack = 0xFFFFFFFF; miPack = new EQApplicationPacket<MoveItem>(AppOpCode.MoveItem, mi); this.Client.SendApplicationPacket(miPack); } } CalcStatModifiers(); }
internal void MovePlayer(ZonePlayer zp, uint zoneId, uint instanceId, float x, float y, float z, float heading, ZoneMode zm) { if (zoneId == this.Zone.ZoneID) { // TODO: also test if the instance id is equal to this zone's if (zp.IsAIControlled) { // TODO: quick move the pc return; } // TODO: if they have a pet, quick move the pet to the new spot as well } zp.ZoneMode = zm; switch (zm) { case ZoneMode.EvacToSafeCoords: case ZoneMode.ZoneToSafeCoords: // TODO: start cheat timer? zp.ZoneSummonX = x; zp.ZoneSummonY = y; zp.ZoneSummonZ = z; zp.Heading = heading; break; case ZoneMode.GMSummon: zp.MsgMgr.SendSpecialMessage(MessageType.Default, "You have been summoned by a GM!"); zp.ZoneSummonX = x; zp.ZoneSummonY = y; zp.ZoneSummonZ = z; zp.Heading = heading; zp.ZoneSummonID = (ushort)zoneId; break; case ZoneMode.Solicited: zp.ZoneSummonX = x; zp.ZoneSummonY = y; zp.ZoneSummonZ = z; zp.Heading = heading; zp.ZoneSummonID = (ushort)zoneId; break; case ZoneMode.ZoneToBindPoint: zp.ZoneId = (ushort)zoneId; zp.X = x; zp.Y = y; zp.Z = z; zp.Heading = heading; _log.InfoFormat("Player {0} has died and will be zoned to bind point in zone {1} at LOC x={2}, y={3}, z={4}", zp.Name, zoneId, x, y, z); ZonePlayerToBind zptb = new ZonePlayerToBind(zoneId, x, y, z, heading, "Bind Location"); EQRawApplicationPacket zptbPack = new EQRawApplicationPacket(AppOpCode.ZonePlayerToBind, zp.Client.IPEndPoint, zptb.Serialize()); QueuePacketToClient(zp.Client, zptbPack, true, ZoneConnectionState.All); return; case ZoneMode.Unsolicited: throw new NotSupportedException("This type of player moving not supported yet. Implement it!"); //break; case ZoneMode.GateToBindPoint: throw new NotSupportedException("This type of player moving not supported yet. Implement it!"); //break; case ZoneMode.SummonPC: zp.MsgMgr.SendSpecialMessage(MessageType.Default, "You have been summoned!"); throw new NotSupportedException("This type of player moving not supported yet. Implement it!"); //break; } // Handle Packet sending wasn't handled yet if we've gotten this far, so handle it now if (zm == ZoneMode.Solicited || zm == ZoneMode.ZoneToSafeCoords) { RequestClientZoneChange rczc = new RequestClientZoneChange() { ZoneId = (ushort)zoneId, X = x, Y = y, Z = z, Heading = heading, InstanceId = (ushort)instanceId, Type = 0x01 // Might be meaningless... noted as an "observed value" }; EQApplicationPacket<RequestClientZoneChange> rczcPack = new EQApplicationPacket<RequestClientZoneChange>(AppOpCode.RequestClientZoneChange, rczc); QueuePacketToClient(zp.Client, rczcPack, true, ZoneConnectionState.Connected); } }