public static void Handle_SummonedHit(WvsGameClient c, CInPacket p) { int dwSummonedID = p.Decode4(); var item = c.Character.Field.Summons[dwSummonedID]; if (item is null) { return; } var nAttackIdx = p.Decode1(); var nDamage = p.Decode4(); var dwMobID = p.Decode4(); var bLeft = p.Decode1(); if (item.nCurHP <= 0 || item.Field.Mobs[dwMobID] is null || item.Field.Mobs[dwMobID].Stats.HP <= 0) { return; } item.Field.Broadcast(CPacket.CSummonedPool.SummonedHit(item, nAttackIdx, nDamage, dwMobID, bLeft)); if (nDamage >= item.nCurHP) { item.nLeaveType = SummonLeaveType.LEAVE_TYPE_SUMMONED_DEAD; item.Field.Summons.Remove(item); } else { item.nCurHP -= (short)nDamage; } }
// actually in CUserLocal::TryDoingMonsterMagnet // but that function is only called by the active which has the name of this class // public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p) { // COutPacket::COutPacket(&oPacket, 103); // LOBYTE(v115) = 2; // v81 = get_update_time(); // COutPacket::Encode4(&oPacket, v81); // COutPacket::Encode4(&oPacket, v76->nSkillID); // COutPacket::Encode1(&oPacket, nSLV); // v82 = nRange; // COutPacket::Encode4(&oPacket, nRange); // for (k = 0; k < v82; ++k) // { // if (apMob.a[k].p) // { // v84 = apMob.a[k].p; // v94 = (int*)v84->_ZtlSecureTear_m_dwMobID_CS; // v85 = _ZtlSecureFuse < unsigned long> (v84->_ZtlSecureTear_m_dwMobID, (unsigned int)v94); // } // else // { // v85 = 0; // } // COutPacket::Encode4(&oPacket, v85); // v86 = anMobMove[k]; // v87 = v86 == 3 || v86 == 4; // COutPacket::Encode1(&oPacket, v87); // } //COutPacket::Encode1(&oPacket, v71->m_nMoveAction & 1); // CClientSocket::SendPacket(TSingleton<CClientSocket>::ms_pInstance, &oPacket); var nCount = p.Decode4(); var apMob = new int[nCount]; for (var i = 0; i > nCount; i++) { apMob[i] = p.Decode4(); var anMobMove = p.Decode1(); // i dont think we need this??? } var bLeft = p.Decode1() > 0; if (c.Skills.Cast(nSkillID, bLeft)) { new UserEffectPacket(UserEffect.SkillUse) { nSkillID = nSkillID, nSLV = nSLV, bLeft = bLeft, dwMobId = nCount > 0 ? apMob[0] : 0, // idk }.BroadcastEffect(c, false); foreach (var dwMobId in apMob) { if (c.Field.Mobs.TryGetValue(dwMobId, out CMob cMob)) { cMob.TryApplySkillDamageStatus(c, nSkillID, nSLV, 0); // todo configure this } } } }
public static void IncCharSlotCount(WvsShopClient c, CInPacket p) { // validate packet length if (p.Available < 9) { return; } p.Decode1(); var cashType = p.Decode4(); var commodityId = p.Decode4(); //Log.Debug("CASH COMMODITY ID: " + commodityId); if (!c.Account.HasCash((CashType)cashType, 6900) || (c.Account.AccountData.CharacterSlots + 3) > #if DEBUG 27 #else Constants.MaxCharSlot #endif ) { c.SendPacket(CPacket.CCashShop.RequestFailPacket(CashItemOps.CashItemRes_Buy_Failed, CashItemFailed.PurchaseLimitOver)); }
private void DecodeAttackInfo(CInPacket p) { for (int i = 0; i < nMobCount; i++) { var info = new AttackEntry(); info.dwMobID = p.Decode4(); info.nHitAction = p.Decode1(); info.nForeAction = p.Decode1(); // COutPacket::Encode1(&v468, v376->nForeAction & 0x7F | (v181 << 7)); info.nFrameIdx = p.Decode1(); // v218 = CMob::GetCurTemplate(v378->pMob) // && (v166 = CMob::GetTemplate(v378->pMob), v166 != CMob::GetCurTemplate(v378->pMob)); // v167 = (_BYTE)v218 << 7; info.CalcDamageStatIndex = p.Decode1(); // COutPacket::Encode1(&v460, v168 & 0x7F | v167); p.Skip(8); // position info info.tDelay = p.Decode2(); for (int j = 0; j < nDamagePerMob; j++) { info.aDamage[j] = Math.Max(0, p.Decode4()); //Log.Debug($"[Damaging Mob] dwMobID: {info.dwMobID} aDamage: {info.aDamage[j]}"); } p.Skip(4); // CMob::GetCrc aAttackInfo[i] = info; } }
public void UserInfoRequest(Character c, CInPacket p) { var dwDickCount = p.Decode4(); var nUserID = p.Decode4(); var pUser = this[nUserID]; if (pUser != null) { c.SendPacket(pUser.CharacterInfo()); } }
/** * Client sends cash item SN. * We index cash items by their serial number. * WZ files indexes cash items by a commodity ID. * The commodity ID (~12000 total) is not used for anything. */ public static void Buy(WvsShopClient c, CInPacket p) { // validate packet length if (p.Available < 9) { return; } p.Decode1(); // 00 var cashType = (CashType)p.Decode4(); var nCommoditySN = p.Decode4(); var commodityInfo = MasterManager.CommodityProvider[nCommoditySN]; if (commodityInfo == null) { return; } if (!commodityInfo.OnSale) { return; // TODO proper error code/response } var item = MasterManager.CreateCashCommodityItem(nCommoditySN); if (item is null) { return; } if (!c.Account.HasCash(cashType, item.NXCost)) { return; // TODO proper error code/response } if (ItemConstants.IsPet(item.nItemID) && InventoryManipulator.GetItemByCashSN(c.Character, InventoryType.Cash, item.SN).Item2 != null) { return; // cant have two of the same pet cuz it screws up our indexing } c.CashLocker.Add(item); #if DEBUG c.Account.ModifyCash(cashType, 10000); Log.Info($"{commodityInfo.CashItemSN}"); #else c.Account.ModifyCash(cashType, -commodityInfo.Price); #endif item.dwAccountID = c.Account.ID; item.dwCharacterID = c.dwCharId; c.SendPacket(CPacket.CCashShop.BuyResponse(item)); // do best items/limited goods handling here }
private void Handle_UserEmotion(WvsGameClient c, CInPacket p) { var nEmotion = p.Decode4(); var nDuration = p.Decode4(); var bByItemOption = p.Decode1(); //if (emote > 7) //{ // int emoteid = 5159992 + emote; // //TODO: As if i care check if the emote is in CS inventory, if not return //} c.GetCharField().Broadcast(CPacket.UserEmoticon(c.Character.CharId, nEmotion, nDuration, bByItemOption), c); }
private void Handle_UserMove(WvsGameClient c, CInPacket p) { var v1 = p.Decode8(); var portalCount = p.Decode1(); //CField::GetFieldKey(v20); var v2 = p.Decode8(); var mapCrc = p.Decode4(); var dwKey = p.Decode4(); var dwKeyCrc = p.Decode4(); var movePath = p.DecodeBuffer(p.Available); c.Character.Position.DecodeMovePath(movePath); c.GetCharField().Broadcast(CPacket.UserMovement(c.Character.CharId, movePath), c); }
public void Move(Character pUser, CInPacket p) { var dwNpcId = p.Decode4(); var item = this[dwNpcId]; if (item == null) { return; } if (item.Controller != pUser) { return; //TODO: Validate you require controller to move a npc } var act1 = p.Decode1(); var act2 = p.Decode1(); byte[] aMovePath = null; if (p.Available > 0) { aMovePath = p.DecodeBuffer(p.Available); } Field.Broadcast(CPacket.NpcMove(item, act1, act2, aMovePath)); }
public void OnPacket(RecvOps opCode, CInPacket p, Character c) { if (c.Stats.nHP <= 0) { return; } var dwID = p.Decode4(); var item = this[dwID]; if (item is null) { return; } switch (opCode) { case RecvOps.CP_ReactorHit: item.Hit(c, p); break; case RecvOps.CP_ReactorTouch: item.Touch(c, p); break; } var provider = ServerApp.Container.Resolve <ScriptManager>(); var script = provider.GetReactorScript (item.sName, item, c.Socket, opCode == RecvOps.CP_ReactorHit); script.Execute(); }
private void Handle_DeleteCharacter(WvsLoginClient c, CInPacket p) { var uid = p.Decode4(); c.SendPacket(CPacket.DeleteCharacter(uid, 0)); //Because I have no pin or pic the game wont let me dlete chars lol }
private void Handle_UserTransferFieldRequest(WvsGameClient c, CInPacket p) { if (p.Available == 0) { //Cash Shop Related return; } //TODO: Portal count checks //TODO: XY rect checks //TODO: Keep track if player spawns when entering a field var portalCount = p.Decode1(); //CField::GetFieldKey(v20); var destination = p.Decode4(); // var portalName = p.DecodeString(); var x = p.Decode2(); var y = p.Decode2(); //var extra = p.DecodeBuffer(3); idk | prem | chase var portal = c.GetCharField() .Portals .GetByName(portalName); if (portal == null) { Logger.Write(LogLevel.Warning, "Client tried to enter non existant portal {0}", portalName); } else { c.UsePortal(portal); } }
public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p) { // Recv [CP_UserSkillUseRequest] [67 00] [D0 B3 75 10] [A6 C7 C9 01] [01] [C0 F7 8D 00] [39 FE] [DF FF] [00] //COutPacket::COutPacket(&oPacket, 103); //v50 = 3; //v36 = get_update_time(); //COutPacket::Encode4(&oPacket, v36); //COutPacket::Encode4(&oPacket, pSkill->nSkillID); //COutPacket::Encode1(&oPacket, nSLV); //COutPacket::Encode4(&oPacket, (unsigned int)cd); //COutPacket::Encode2(&oPacket, pt.x); //COutPacket::Encode2(&oPacket, pt.y); //COutPacket::Encode1(&oPacket, bLeft); //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket); var dwMobID = p.Decode4(); var ptX = p.Decode2(); var ptY = p.Decode2(); var bLeft = p.Decode1() > 0; if (c.Skills.Cast(nSkillID, bLeft)) { new UserEffectPacket(UserEffect.SkillUse) { nSkillID = nSkillID, nSLV = nSLV, bLeft = bLeft, ptX = ptX, ptY = ptY, }.BroadcastEffect(c, false); // TODO spawn monster lol } }
public void OnUpdateRequest(CInPacket p) { var nReq = (MapTransferReq)p.Decode1(); var bExt = p.Decode1() != 0; var pTransfer = bExt ? adwMapTransferEx : adwMapTransfer; switch (nReq) { case MapTransferReq.RegisterList: { var nFieldID = Parent.Field.MapId; if (Parent.Field.Template.HasTeleportItemLimit() || !AddLocation(pTransfer, nFieldID)) { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.RegisterFail, bExt)); } else { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.RegisterList, bExt, pTransfer)); } break; } case MapTransferReq.DeleteList: { int nFieldID = p.Decode4(); RemoveLocation(pTransfer, nFieldID); Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.DeleteList, bExt, pTransfer)); break; } } }
private void Handle_UserSelectNpc(WvsGameClient c, CInPacket p) { var dwNpcId = p.Decode4(); var nPosX = p.Decode2(); var nPosY = p.Decode2(); if (c.NpcScript != null) { Logger.Write(LogLevel.Warning, "Npc script already in progress?"); } var field = c.GetCharField(); var npc = field.Npcs.Get(dwNpcId); if (npc != null) { //if (npc.hasShop()) //{ // chr.setConversation(1); // npc.sendShop(c); //} //else { c.NpcScript = NpcScript.GetScript(npc.Id, c); c.NpcScript.Execute(); } } else { Logger.Write(LogLevel.Warning, "Unable to find NPC {0}", dwNpcId); } }
public void OnCompleteQuest(CInPacket p, short nQuestID, int dwNpcTemplateID, bool bIsAutoComplete) { var nSelect = bIsAutoComplete ? -1 : p.Decode4(); if (!CheckDemand(nQuestID, dwNpcTemplateID, 1)) { Parent.SendPacket(CPacket.CQuestMan.UserQuestResult(QuestResultType.Failed_Unknown, null)); return; } var nActCompleteResult = TryQuestAct(nQuestID, 1); if (nActCompleteResult == QuestResultType.Failed_Unknown) { return; } if (nActCompleteResult == QuestResultType.Success) { this[nQuestID].tCompleted = DateTime.Now; this[nQuestID].nState = QuestActType.QuestComplete; } var endActNextQuest = MasterManager.QuestTemplates[nQuestID].EndAct?.NextQuest ?? 0; Parent.SendPacket(CPacket.CQuestMan .UserQuestResult(nActCompleteResult, this[nQuestID], dwNpcTemplateID, (short)endActNextQuest)); }
private void Handle_UserChangeSlotPositionRequest(WvsGameClient c, CInPacket p) { var tick = p.Decode4(); var type = p.Decode1(); // inventory var src = p.Decode2(); var dst = p.Decode2(); var quantity = p.Decode2(); Logger.Write(LogLevel.Debug, "UserChangeSlotPositionRequest Src {0}, Dst {1} Type {2} Qty {3}", src, dst, type, quantity); if (src < 0 && dst > 0) { CInventoryManipulator.UnEquip(c, src, dst); //check } else if (dst < 0) { CInventoryManipulator.Equip(c, src, dst); //check } else if (dst == 0) { CInventoryManipulator.Drop(c, type, src, quantity); } else { CInventoryManipulator.Move(c, type, src, dst); //check } }
public void OnQuickslotKeyMapped(CInPacket p) { for (int i = 0; i < 8; i++) { Insert(93 + 1, 8, p.Decode4()); } }
public static void UserChat(WvsGameClient c, CInPacket p) { p.Decode4(); var sText = p.DecodeString(); var bOnlyBalloon = p.Decode1() != 0; if (sText.Length >= sbyte.MaxValue) { return; } var handle = ServerApp.Container.Resolve <CommandHandle>(); if (!handle.Execute(c.Character, sText)) { var bAdmin = c.Account.AccountData.Admin > 0; CCurseProcess.ProcessString(sText, out var output); if (output.Length <= 0) { return; } c.Character.Field.Broadcast(CPacket.UserChat(c.Character.dwId, output, bAdmin, bOnlyBalloon)); } }
public static void DeleteCharacter(WvsLoginClient c, CInPacket p) { var szSPW = p.DecodeString(); var dwCharID = p.Decode4(); // TODO check for guild ownership and family membership byte nRetCode = 0x09; //Error var aCharList = c.Account.LoadCharIdList(); if (aCharList.Contains(dwCharID)) { using (var conn = new NpgsqlConnection(Constants.DB_World0_ConString)) { conn.Open(); using (var cmd = new NpgsqlCommand($"DELETE FROM {Constants.DB_All_World_Schema_Name}.characters WHERE id = {dwCharID}", conn)) { cmd.ExecuteNonQuery(); } } nRetCode = 0; //Success } c.SendPacket(CPacket.CLogin.DeleteCharacter(dwCharID, nRetCode)); }
public void Hit(Character c, CInPacket p) { // CReactorPool::FindHitReactor // CReactorPool::FindSkillReactor var bSkillReactor = p.Decode4() != 0; if (bSkillReactor) { return; // TODO handle this } var dwHitOption = p.Decode4(); // v4->dwHitOption = v13 & 1 | 2 * CUser::IsOnFoothold(v3); var tActionDelay = p.Decode2(); var nSkillID = p.Decode4(); // for skill reactors?? idk yet OnHitReactor(c, tActionDelay, 0); // TODO event idx }
public static void Handle_UserShopRequest(WvsGameClient c, CInPacket p) { if (c.ActiveShop is null) { c.Character.SendMessage("Unable to find active shop. Please re-open the shop or report this to staff."); return; } switch ((ShopReq)p.Decode1()) // nOperation { case ShopReq.Buy: { var nPos = p.Decode2(); //Item index within the npc shop lol var dwTemplateID = p.Decode4(); var nCount = p.Decode2(); BuyItem(c.Character, nPos, dwTemplateID, nCount); break; } case ShopReq.Sell: { var nSlot = p.Decode2(); //Item inventory index var dwTemplateID = p.Decode4(); var nCount = p.Decode2(); SellItem(c.Character, nSlot, dwTemplateID, nCount); break; } case ShopReq.Recharge: { var nSlot = p.Decode2(); RechargeItem(c.Character, nSlot); break; } case ShopReq.Close: { Close(c.Character); break; } } }
/** * Die packet: * Recv [CP_UserTransferFieldRequest] [29 00] [01] [00 00 00 00] 00 00 00 01 00 // last bytes possibly related to death-items * Portal to other map packet: * Recv [CP_UserTransferFieldRequest] [29 00] [01] [FF FF FF FF] [06 00] [65 61 73 74 30 30] [4D 06] [C7 01] 00 00 00 */ public static void Field(WvsGameClient c, CInPacket p) { //void __thiscall CUser::OnTransferFieldRequest(CUser *this, int bLoopback, CInPacket *iPacket) //Exit Cash Shop -> Not used in WvsGame if (p.Available == 0) { return; } //TODO: Portal count checks //TODO: XY rect checks to ensure player is on portal when activating it //TODO: Keep track if player spawns when entering a field var bFieldKey = p.Decode1(); //CField::GetFieldKey(v20); var dwField = p.Decode4(); var sPortalName = p.DecodeString(); if (c.Character.Stats.nHP <= 0) { c.Character.Field.OnUserWarpDie(c.Character); } else if (sPortalName.Length > 0) // not death { var x = p.Decode2(); var y = p.Decode2(); p.Decode1(); // used to be bTownPortal var bPremium = p.Decode1(); var bChase = p.Decode1(); if (bChase > 0) { var nTargetPosition_X = p.Decode4(); var nTargetPosition_Y = p.Decode4(); } c.Character.Field.OnUserEnterPortal(c.Character, sPortalName); } else // gm warp command { // TODO admin checks // tp to desired field } }
public static MapleAttack ParseBody(CInPacket p, Character c) { return(ParseMelee(p, c)); //TODO: Confirm below one day. Delta said melee works for this // Recv [CP_UserBodyAttack] [32 00] [01] [FF FF FF FF] [FF FF FF FF] [11] [FF FF FF FF] [FF FF FF FF] [CB F9 41 01] [00] [C3 C0 24 6A] [1F 46 7E D1] [9D D4 DD D5] [9D D4 DD D5] [00 00] 80 5F CF 88 C3 02 00 F9 9E D9 1F 00 00 00 00 2F 27 00 00 07 00 01 05 A9 00 8B 01 A5 00 8B 01 00 00 0B 00 00 00 B8 8D DB 27 B9 00 8B 01 MapleAttack ret = new MapleAttack(); p.Decode1(); // field key p.Decode4(); // pDrInfo.dr0 p.Decode4(); // pDrInfo.dr1 ret.nDamagePerMob = (byte)(p.Decode1() & 0xF); // nDamagePerMob | 0x10 * nRange p.Decode4(); // pDrInfo.dr2 p.Decode4(); // pDrInfo.dr3 ret.nSkillID = p.Decode4(); ret.ValidateSkill(c); if (!ret.bValidAttack) { return(ret); } p.Decode1(); // cd->nCombatOrders p.Decode4(); // get_rand(pDrInfo.dr0, 0) p.Decode4(); // CCrc32::GetCrc32(pData, 4u, n, 0, 0) // todo lol return(null); }
public void OnPetPacket(RecvOps opCode, CInPacket p) { switch (opCode) { case RecvOps.CP_PetDropPickUpRequest: break; case RecvOps.CP_PetInteractionRequest: break; case RecvOps.CP_UserActivatePetRequest: break; case RecvOps.CP_UserDestroyPetItemRequest: break; default: var liPetLockerSN = p.Decode8(); var item = Pets.FirstOrDefault(pet => pet.liPetLockerSN == liPetLockerSN); if (item is null) { return; } switch (opCode) { case RecvOps.CP_PetMove: item.Move(p); break; case RecvOps.CP_PetStatChangeItemUseRequest: // CPet::OnNameChanged(v4, iPacket); break; case RecvOps.CP_PetUpdateExceptionListRequest: break; case RecvOps.CP_PetAction: case RecvOps.CP_PetActionCommand: var tick = p.Decode4(); var nType = p.Decode1(); var nAction = p.Decode1(); var sMsg = p.DecodeString(); // rebroadcasting this is bad practice Parent.Field.Broadcast(item.PetActionCommand((PetActType)nType, nAction, true, true), Parent); break; } break; } }
/** * Cash packages have data in both the Commodity and Package section of Etc.wz * Client sends package SN which is stored in the commodity section of WZ files (one of the ~12000 entries) * The commodity itemid (not SN) contains the SN for the CashPackage * The CashPackage (one of ~450) contains the cash item SN's of the package items */ public static void BuyPackage(WvsShopClient c, CInPacket p) { if (p.Available < 9) { return; } p.Decode1(); // 00 var cashType = (CashType)p.Decode4(); var nCommoditySN = p.Decode4(); var commodityInfo = MasterManager.CommodityProvider[nCommoditySN]; if (commodityInfo is null) { return; } if (!commodityInfo.OnSale) { return; // TODO proper error code/response } if (!c.Account.HasCash(cashType, commodityInfo.Price)) { return; // TODO proper error code/response } var packagedata = MasterManager.CreateCashPackageItems(commodityInfo.ItemID); packagedata.ForEach(item => { item.dwAccountID = c.Account.ID; item.dwCharacterID = c.dwCharId; }); #if RELEASE c.Account.ModifyCash(cashType, -commodityInfo.Price); #else foreach (var item in packagedata) { item.dwAccountID = c.Account.ID; item.dwCharacterID = c.dwCharId; c.Account.AccountData.Locker.Add(item); } Log.Info($"================COMMODITYSN {nCommoditySN}"); // temporary so i can quickly find a buncha serial numbers return; #endif c.SendPacket(CPacket.CCashShop.BuyPackageResponse(packagedata)); }
public static void Handle_Whisper(WvsGameClient c, CInPacket p) { // Recv [CP_Whisper] [8D 00] [05] [7C 9E D7 14] [05 00] [70 65 6E 69 73] var flag = p.Decode1(); // COutPacket::Encode1((COutPacket *)&oPacket, ((v44 == 0) + 1) | 4); p.Decode4(); // tick var name = p.DecodeString(); if (name.Length > 13) { return; } var pTargetUser = MasterManager.CharacterPool.Get(name, false); if (pTargetUser is null) // will not be null if char is in itc or cs { c.SendPacket(WhisperResult(name, false)); return; } switch (flag) // todo make this an enumerator { case 5: // /find command { var nTargetChannel = pTargetUser.ChannelID; if (MasterManager.CharacterPool.CharInCashShop(pTargetUser.dwId)) { c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.CS)); } else if (nTargetChannel == c.ChannelId) { c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.SameChannel, pTargetUser.Field.MapId)); } else { c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.DifferentChannel, pTargetUser.ChannelID)); } } break; case 6: // whisper { var msg = p.DecodeString(); if (msg.Length > 75) { return; // PE or trying to find player } pTargetUser.SendPacket(WhisperMessage(c.Character.Stats.sCharacterName, c.Character.ChannelID, c.Character.Account?.AccountData.Admin > 0, msg)); c.SendPacket(WhisperResult(c.Character.Stats.sCharacterName, true)); } break; } }
public static int[] DecodeIntArray(this CInPacket packet, int nCount) { var retVal = new int[nCount]; for (var i = 0; i < nCount; i++) { retVal[i] = packet.Decode4(); } return(retVal); }
// note: uses another header (0x69) than regular skill req (0x67) public static void Handle(WvsGameClient c, CInPacket p) { //COutPacket::COutPacket(&oPacket, 105); //v71 = 10; //COutPacket::Encode4(&oPacket, v5); //COutPacket::Encode1(&oPacket, nSLV); //COutPacket::Encode2(&oPacket, v4->m_nOneTimeAction & 0x7FFF | ((unsigned __int16)v4->m_nMoveAction << 15)); //COutPacket::Encode1(&oPacket, v57); //if (v5 == 33101005) // COutPacket::Encode4(&oPacket, v4->m_dwSwallowMobID); //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket); var nSkillID = p.Decode4(); var nSLV = p.Decode1(); var nMoveAction = p.Decode2(); var nActionSpeed = p.Decode1(); var pSkill = c.Character.Skills.Get(nSkillID, true); if (pSkill is null) { return; } if (nSkillID == (int)Skills.WILDHUNTER_SWALLOW) { var dwSwallowMobId = p.Decode4(); var pMob = c.Character.Field.Mobs[dwSwallowMobId]; if (pMob is object && !GameConstants.is_not_swallowable_mob(pMob.nMobTemplateId)) { if (!pMob.TrySwallowMob(c.Character)) { return; } } } c.Character.Field.Broadcast(UserSkillPrepare(c.Character.dwId, nSkillID, pSkill.nSLV, nMoveAction, nActionSpeed), c); }
public void OnPacket(WvsGameClient c, CInPacket p) { var ownerId = p.Decode4(); if (Contains(ownerId)) { if (c.Character.Party?.TryGetValue(ownerId, out PartyMember item) ?? false) { c.Character.Action.SetField(Field.ReturnMapId); } } }