public static void Handle(int nSkillID, byte nSLV, Character character, CInPacket p) { // COutPacket::COutPacket(&oPacket, 103); // LOBYTE(v37) = 2; // v23 = get_update_time(); // COutPacket::Encode4(&oPacket, v23); // COutPacket::Encode4(&oPacket, pSkill->nSkillID); // COutPacket::Encode1(&oPacket, nSLV); // v24 = adwUserID.a; // if (adwUserID.a) // v25 = *(adwUserID.a - 1); // else // LOBYTE(v25) = 0; // COutPacket::Encode1(&oPacket, v25); // v26 = 0; // if (ZArray < unsigned long>::GetCount(&adwUserID) ) //{ // do // COutPacket::Encode4(&oPacket, v24[v26++]); // while (v26 < ZArray < unsigned long>::GetCount(&adwUserID) ); // } // COutPacket::Encode2(&oPacket, (unsigned __int16)cd); // CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket); var v25 = p.Decode1(); var ZArray = p.DecodeIntArray(v25); var cd = p.Decode2(); }
/// <summary> /// Client sends an updated wish list when something is changed. /// Wish list max size is 10. /// Client expects to receive a full wish list packet back. /// </summary> /// <param name="c"></param> /// <param name="p"></param> public static void ModifyWishList(WvsShopClient c, CInPacket p) { if (p.Available < 40) { return; } c.Character.Stats.WishList = p.DecodeIntArray(10); c.SendPacket(CPacket.CCashShop.WishListData(c, true)); c.EnableActions(); }
public void OnLostQuestItem(CInPacket p, short nQuestID) { var nLostCount = p.Decode4(); var pAct = MasterManager.QuestTemplates[nQuestID].StartAct; if (pAct is null) { return; // invalid quest ID } if (nLostCount <= 0 || pAct.Items.Length <= 0) { return; // TODO trigger AB, close socket } var aLostItem = p.DecodeIntArray(nLostCount); foreach (var item in pAct.Items) { if (!aLostItem.Contains(item.Item.ItemID)) { continue; // TODO trigger AB? } if (ItemConstants.GetInventoryType(item.Item.ItemID) == InventoryType.Equip) { Parent.SendMessage("Not currently supported. Check again later."); return; // TODO } if (!MasterManager.ItemTemplates[item.Item.ItemID]?.Quest ?? true) { continue; } if (InventoryManipulator.HasSpace(Parent, item.Item.ItemID, (short)item.Item.Count)) { var itemToAdd = MasterManager.CreateItem(item.Item.ItemID); itemToAdd.nNumber = (short)item.Item.Count; InventoryManipulator.InsertInto(Parent, itemToAdd); } else { // TODO proper response packet Parent.SendMessage("Please make space in your inventory."); return; } } // TODO // if ( aChangedItem.a && *(aChangedItem.a - 1) > 0u ) // CUser::PostQuestEffect(&v16->vfptr, 1, &aChangedItem, 0, 0); }
public static void Handle_GroupMessage(WvsGameClient c, CInPacket p) { // : [8C 00] [5B BE 87 0F] [01] [01] [69 04 00 00] [03 00] [61 73 64] var get_update_time = p.Decode4(); var nChatTarget = p.Decode1(); var nMemberCnt = p.Decode1(); var aMemberList = p.DecodeIntArray(nMemberCnt); var sText = p.DecodeString(); // [INFO] Recv [CP_GroupMessage] 8C 00 30 9F 4F 0F 01 01 69 04 00 00 05 00 61 73 64 77 64 if (sText.Length >= sbyte.MaxValue) { c.Character.SendMessage("Chat message exceeded allowed length."); return; } MasterManager.Log.Debug("Text: " + sText); switch ((GroupMessageType)nChatTarget) { case GroupMessageType.BuddyChat: c.Character.Friends.HandleBuddyChat(sText, aMemberList); break; case GroupMessageType.PartyChat: c.Character.Party?.HandlePartyChat(c.Character.dwId, c.Character.Stats.sCharacterName, sText); break; case GroupMessageType.ExpeditionChat: // todo break; case GroupMessageType.GuildChat: // todo break; case GroupMessageType.AllianceChat: // todo break; } }
public static void Handle_SummonedAttack(WvsGameClient c, CInPacket p) { var dwSummonedID = p.Decode4(); var item = c.Character.Field.Summons[dwSummonedID]; if (item is null) { return; } var nSkillID = item.nSkillID; p.Skip(8); // crc p.Decode4(); // get_update_time() p.Skip(8); // crc var nActionAndDir = p.Decode1(); var nAction = nActionAndDir & 0x7F; var bLeft = ((nAction >> 7) & 1) > 0; p.Skip(8); // crc var nMobCount = p.Decode1(); if (nSkillID == (int)Skills.MECHANIC_TESLA_COIL && nAction != 0x10) { var adwTeslaFamily = p.DecodeIntArray(3); } p.Skip(8); // mob pos, summon pos p.Skip(4); var deadMobs = new List <int>(); var aSAI = new List <SummonAttackInfo>(); for (var i = 0; i < nMobCount; i++) { var dwMobID = p.Decode4(); var pMob = item.Field.Mobs[dwMobID]; var dwTemplateID = p.Decode4(); var nHitAction = p.Decode1(); var nForeAction = p.Decode1(); var nFrameIdx = p.Decode1(); var nCalcDamageStatIndex = p.Decode1(); p.Skip(8); // position var tDelay = p.Decode2(); var nDamage = p.Decode4(); if (nDamage <= 0) { continue; } if (pMob is null || pMob.Dead || pMob.Template.Invincible) { continue; // this happens naturally when two summons attack the same mob at the same time } aSAI.Add(new SummonAttackInfo { dwMobID = dwMobID, nHitAction = nHitAction, nDamage = nDamage }); if (pMob.Damage(c.Character, nDamage, tDelay)) { deadMobs.Add(dwMobID); } } item.Field.Broadcast(CPacket.CSummonedPool.SummonedAttack(item, item.dwId, nActionAndDir, aSAI), c.Character); deadMobs.ForEach(mob => c.Character.Field.Mobs.Remove(mob)); if (nAction == 0x10) { item.nLeaveType = SummonLeaveType.LEAVE_TYPE_SELF_DESTRUCT; item.Field.Summons.Remove(item); } else if (nSkillID == (int)Skills.VALKYRIE_GABIOTA) { item.nLeaveType = SummonLeaveType.LEAVE_TYPE_GABIOTA; item.Field.Summons.Remove(item); } }