public static void Handle(int nSkillID, byte nSLV, Character c, CInPacket p) { // Recv [CP_UserSkillUseRequest] 67 00 56 3B 36 10 A5 C7 C9 01 01 2A 4E 00 00 //COutPacket::COutPacket(&oPacket, 103); //v55 = 8; //v41 = get_update_time(); //COutPacket::Encode4(&oPacket, v41); //COutPacket::Encode4(&oPacket, pSkill->nSkillID); //COutPacket::Encode1(&oPacket, nSLV); //v42 = CMob::GetMobID(v24); //COutPacket::Encode4(&oPacket, v42); //CClientSocket::SendPacket(TSingleton < CClientSocket >::ms_pInstance, &oPacket); var dwMobId = p.Decode4(); var pMob = c.Field.Mobs[dwMobId]; if (pMob is null || GameConstants.is_not_capturable_mob(pMob.nMobTemplateId) || pMob.MaxHp * 0.5 > pMob.Stats.HP || !JobLogic.IsWildhunterJob(c.Stats.nJob)) { return; } var bLeft = pMob.Position.X < c.Position.X; var bSuccess = c.Skills.Cast(nSkillID, bLeft); if (bSuccess) { new UserEffectPacket(UserEffect.SkillUse) { nSkillID = nSkillID, nSLV = nSLV }.BroadcastEffect(c, false); //c.SendPacket(c.WildHunterInfo.CaptureResultLocalEffect(WildHunterCaptureResult.Success)); //c.Field.Broadcast(c.WildHunterInfo.CaptureSuccessRemoteEffect(), c); c.Field.Mobs.Remove(pMob); c.WildHunterInfo.UpdateJaguarInfo(pMob.nMobTemplateId); } }
public static int get_weapon_mastery(Character cd, int nWeaponItemID, int nAttackType, int nSkillID, out int pnACCInc, out int pnPADInc) { pnACCInc = 0; pnPADInc = 0; var mastery = 0; // TODO clean this function up -> ugly af :( switch ((WeaponType)ItemConstants.get_weapon_type(nWeaponItemID)) { case WeaponType.WT_OH_SWORD: case WeaponType.WT_TH_SWORD: if (nAttackType > 0) { if (nSkillID != (int)Skills.SOULMASTER_SOUL_BLADE) { return(mastery); } if (nAttackType != 1) { return(mastery); } } mastery = get_mastery_from_skill(cd, Skills.FIGHTER_WEAPON_MASTERY, out pnACCInc); if (mastery == 0) { mastery = get_mastery_from_skill(cd, Skills.PAGE_WEAPON_MASTERY, out pnACCInc); if (mastery != 0) { if (cd.Stats.SecondaryStats.rWeaponCharge != 0) { var tempmastery = get_mastery_from_skill(cd, Skills.PALADIN_ADVANCED_CHARGE, out var pnSubACCInc); if (tempmastery > 0) { pnACCInc = pnSubACCInc; mastery = tempmastery; } } } else { mastery = get_mastery_from_skill(cd, Skills.SOULMASTER_SWORD_MASTERY, out pnACCInc); } } break; case WeaponType.WT_OH_AXE: case WeaponType.WT_TH_AXE: if (nAttackType != 0) { return(0); } mastery = get_mastery_from_skill(cd, Skills.FIGHTER_WEAPON_MASTERY, out pnACCInc); break; case WeaponType.WT_OH_MACE: case WeaponType.WT_TH_MACE: if (nAttackType != 0) { return(0); } mastery = get_mastery_from_skill(cd, Skills.PAGE_WEAPON_MASTERY, out pnACCInc); if (cd.Stats.SecondaryStats.rWeaponCharge != 0) { var tempmastery = get_mastery_from_skill(cd, Skills.PALADIN_ADVANCED_CHARGE, out var pnSubACCInc); if (tempmastery > 0) { pnACCInc = pnSubACCInc; mastery = tempmastery; } } break; case WeaponType.WT_DAGGER: if (nAttackType != 0) { return(0); } var pSubDaggerItemSlot = cd.EquippedInventoryNormal.Get((short)BodyPart.BP_SHIELD); var bSubDagger = ItemConstants.get_weapon_type(pSubDaggerItemSlot.nItemID) == (int)WeaponType.WT_SUB_DAGGER; mastery = get_mastery_from_skill(cd, bSubDagger ? Skills.DUAL1_DUAL_MASTERY : Skills.THIEF_DAGGER_MASTERY, out pnACCInc); break; case WeaponType.WT_SPEAR: if (nAttackType != 0) { return(0); } mastery = get_mastery_from_skill(cd, Skills.SPEARMAN_WEAPON_MASTERY, out pnACCInc); break; case WeaponType.WT_POLEARM: if (nAttackType != 0 && (nSkillID != (int)Skills.ARAN_COMBO_SMASH && nSkillID != (int)Skills.ARAN_COMBO_FENRIR && nSkillID != (int)Skills.ARAN_COMBO_TEMPEST || nAttackType != 1)) { return(mastery); } if (JobLogic.isAran(cd.Stats.nSubJob)) { mastery = get_mastery_from_skill(cd, Skills.ARAN_POLEARM_MASTERY, out pnACCInc); var highMastery = get_mastery_from_skill(cd, Skills.ARAN_HIGH_MASTERY, out pnPADInc); if (highMastery != 0) { mastery = highMastery; } } else { mastery = get_mastery_from_skill(cd, Skills.SPEARMAN_WEAPON_MASTERY, out pnACCInc); if (cd.Stats.SecondaryStats.rBeholder != 0) { mastery += get_mastery_from_skill(cd, Skills.DARKKNIGHT_BEHOLDER, out _); } } break; case WeaponType.WT_BOW: if (nAttackType != 1) { return(mastery); } int bowexpert; if (JobLogic.IsKOC(cd.Stats.nJob)) { mastery = get_mastery_from_skill(cd, Skills.WINDBREAKER_BOW_MASTERY, out pnACCInc); bowexpert = get_mastery_from_skill(cd, Skills.WINDBREAKER_BOW_EXPERT, out pnPADInc); } else { mastery = get_mastery_from_skill(cd, Skills.HUNTER_BOW_MASTERY, out pnACCInc); bowexpert = get_mastery_from_skill(cd, Skills.BOWMASTER_BOW_EXPERT, out pnPADInc); } if (bowexpert != 0) { mastery = bowexpert; } break; case WeaponType.WT_CROSSBOW: var bWildhunterJob = JobLogic.IsWildhunterJob(cd.Stats.nJob); if (nAttackType != 1 && (!bWildhunterJob || nAttackType != 0)) { return(mastery); } int xbowexpert; if (bWildhunterJob) { mastery = get_mastery_from_skill(cd, Skills.WILDHUNTER_CROSSBOW_MASTERY, out pnACCInc); xbowexpert = get_mastery_from_skill(cd, Skills.WILDHUNTER_CROSSBOW_EXPERT, out pnPADInc); } else { mastery = get_mastery_from_skill(cd, Skills.CROSSBOWMAN_CROSSBOW_MASTERY, out pnACCInc); xbowexpert = get_mastery_from_skill(cd, Skills.CROSSBOWMASTER_CROSSBOW_EXPERT, out pnPADInc); } if (xbowexpert != 0) { mastery = xbowexpert; } break; case WeaponType.WT_THROWINGGLOVE: if (nAttackType != 1 && (nSkillID != (int)Skills.NIGHTWALKER_POISON_BOMB || nAttackType != 0)) { return(mastery); } if (JobLogic.IsKOC(cd.Stats.nJob)) { mastery = get_mastery_from_skill(cd, Skills.NIGHTWALKER_JAVELIN_MASTERY, out pnACCInc); } else { mastery = get_mastery_from_skill(cd, Skills.ASSASSIN_JAVELIN_MASTERY, out pnACCInc); } break; case WeaponType.WT_KNUCKLE: if (nAttackType != 0 && (nSkillID != (int)Skills.VIPER_ENERGY_ORB && nSkillID != (int)Skills.STRIKER_SHARK_WAVE || nAttackType != 1)) { return(mastery); } if (JobLogic.IsKOC(cd.Stats.nJob)) { mastery = get_mastery_from_skill(cd, Skills.STRIKER_KNUCKLE_MASTERY, out pnACCInc); } else { mastery = get_mastery_from_skill(cd, Skills.INFIGHTER_KNUCKLE_MASTERY, out pnACCInc); } break; case WeaponType.WT_GUN: if (nAttackType != 1 && (nSkillID != (int)Skills.CAPTAIN_AIR_STRIKE || nAttackType != 0)) { return(mastery); } if (JobLogic.is_mechanic_job(cd.Stats.nJob)) { mastery = get_mastery_from_skill(cd, Skills.MECHANIC_HN07_UPGRADE, out pnACCInc); if (mastery == 0) { mastery = get_mastery_from_skill(cd, Skills.MECHANIC_HN07, out pnACCInc); } } else { mastery = get_mastery_from_skill(cd, Skills.GUNSLINGER_GUN_MASTERY, out pnACCInc); } break; } return(mastery); }
public static MapleAttack ParseShoot(CInPacket p, Character c) { MapleAttack ret = new MapleAttack(); p.Skip(8); // -1 var tByte1 = p.Decode1(); ret.nDamagePerMob = (byte)(tByte1 & 0xF); ret.nMobCount = (byte)((tByte1 >> 4) & 0xF); //c.SendMessage("Damage per mob " + ret.nDamagePerMob); //c.SendMessage("Mob count " + ret.nMobCount); p.Skip(8); //-1 ret.nSkillID = p.Decode4(); //2017 ret.ValidateSkill(c); if (!ret.bValidAttack) { return(ret); } var skillTemplate = MasterManager.SkillTemplates[ret.nSkillID]; var nCombatOrders = p.Decode1(); // nCombatOrders p.Skip(4); // get_rand(pDrInfo.dr0, 0); p.Skip(4); // CCrc32::GetCrc32(pData, 4u, n, 0, 0); p.Skip(8); ret.tKeyDown = skillTemplate?.is_keydown_skill ?? false?p.Decode4() : -1; ret.nOption = p.Decode1(); //COutPacket::Encode1(&v498, (bSpark << 7) | (bSpiritJavelin << 6) | 8 * bShadowPartner | 4 * bMortalBlow | 2 * bSoulArrow); var bSpark = (ret.nOption & 0x80) != 0; var bSpiritJavelin = (ret.nOption & 0x40) != 0; var bSerial = (ret.nOption & 0x20) != 0; var bShadowPartner = (ret.nOption & 0x8) != 0; var bMortalBlow = (ret.nOption & 0x4) != 0; var bSoulArrow = (ret.nOption & 0x2) != 0; ret.bNextShootExJablin = p.Decode1() > 0; //v339->m_bNextShootExJablin && CUserLocal::CheckApplyExJablin(v339, pSkill, nAttackAction); ret.nActionAndDir = p.Decode2(); ret.bLeft = (ret.nActionAndDir >> 15) & 1; ret.nAction = ret.nActionAndDir & 0x7FFF; //nAttackAction p.Skip(4); //CRC i think ret.nAttackActionType = p.Decode1(); //nAttackSpeed | 16 * nReduceCount ret.nAttackSpeed = p.Decode1(); ret.tAttackTime = p.Decode4(); p.Skip(4); //nPhase ret.nBulletItemPos = p.Decode2(); ret.nBulletCashItemPos = p.Decode2(); var nShootRange0a = p.Decode1(); // nSLV (BMS) ret.bNoItemConsume = skillTemplate?.is_shoot_skill_not_consuming_bullet ?? false; if (!ret.bNoItemConsume) { if (JobLogic.is_mechanic_job(c.Stats.nJob)) { ret.bNoItemConsume = true; } else if (bSoulArrow) { ret.bNoItemConsume = c.Buffs[(int)Skills.HUNTER_SOUL_ARROW_BOW] != null || c.Buffs[(int)Skills.CROSSBOWMAN_SOUL_ARROW_CROSSBOW] != null || c.Buffs[(int)Skills.WINDBREAKER_SOUL_ARROW_BOW] != null || c.Buffs[(int)Skills.WILDHUNTER_SOUL_ARROW_CROSSBOW] != null; } else if (bSpiritJavelin) { if (ret.bNextShootExJablin) { ret.bNextShootExJablin = false; } else { ret.nSpiritJavelinItemID = p.Decode4(); var nBulletType = (ret.nSpiritJavelinItemID % 10000) + 1; c.Buffs.TryGetValue((int)Skills.NIGHTLORD_SPIRIT_JAVELIN, out AbstractBuff secondaryStat_nSpiritJavelin); if (c.InventoryConsume.Get(ret.nBulletItemPos)?.nItemID != ret.nSpiritJavelinItemID) { c.Buffs.Remove((int)Skills.NIGHTLORD_SPIRIT_JAVELIN); // they have to use the same item as they } else { if (secondaryStat_nSpiritJavelin != null && nBulletType != secondaryStat_nSpiritJavelin.Stat[SecondaryStatFlag.SpiritJavelin].nValue) { ret.bValidAttack = false; // PE return(ret); } ret.bNoItemConsume = true; } } } else if (ret.bNextShootExJablin) { ret.bNoItemConsume = true; } } ret.DecodeAttackInfo(p); p.Skip(4); // char pos if (JobLogic.IsWildhunterJob(c.Stats.nJob)) { var m_ptBodyRelMove = p.Decode2(); // unsure what this is used for } p.Skip(4); // another pos.. unsure for what if (ret.nSkillID == (int)Skills.STRIKER_SPARK) { ret.tReserveSpark = p.Decode4(); } return(ret); }
/// <summary> /// Sends migratein packet depending on character migration status. /// Triggers OnUserEnter() for child classes /// Notifies proper social channels /// </summary> /// <param name="c"></param> public void AddClient(WvsGameClient c) { var character = c.Character; var bSendPartyMapChangeUpdate = c.MigratedIn; if (Template.HasNoPetLimit()) { character.Stats.aliPetLockerSN = new long[3]; // clear pets character.Pets.Dispose(); } if (Template.HasSummonLimit()) { MasterManager.SummonStorage.Retrieve(character.dwId); // clear incoming summons } if (c.MigratedIn) { var p = CPacket.SetField(character, c.ChannelId, c.WorldID); c.SendPacket(p); } else { c.MigratedIn = true; #if DEBUG character.Stats.nPortal = 0; //Spawn everyone in same place #else var sp = Portals.GetRandStartPoint(); if (sp != null) { var foothold = Footholds.FindBelow(sp.nX, sp.nY); if (foothold != null) { character.Stats.nPortal = (byte)sp.nIdx; character.Position.X = foothold.X1; character.Position.Y = foothold.Y1; character.Position.Foothold = foothold.Id; } } #endif //TODO: Refine our flags for production var dbFlag = (DbCharFlags)0; //dbFlag |= DbCharFlags.ALL; dbFlag |= DbCharFlags.CHARACTER; dbFlag |= DbCharFlags.MONEY; dbFlag |= DbCharFlags.INVENTORYSIZE; dbFlag |= DbCharFlags.ITEMSLOTEQUIP; dbFlag |= DbCharFlags.ITEMSLOTCONSUME; dbFlag |= DbCharFlags.ITEMSLOTINSTALL; dbFlag |= DbCharFlags.ITEMSLOTETC; dbFlag |= DbCharFlags.ITEMSLOTCASH; dbFlag |= DbCharFlags.SKILLRECORD; dbFlag |= DbCharFlags.SKILLCOOLTIME; dbFlag |= DbCharFlags.QUESTRECORD; dbFlag |= DbCharFlags.QUESTCOMPLETE; //dbFlag |= DbCharFlags.MINIGAMERECORD; dbFlag |= DbCharFlags.COUPLERECORD; dbFlag |= DbCharFlags.MONSTERBOOKCOVER; dbFlag |= DbCharFlags.MONSTERBOOKCARD; dbFlag |= DbCharFlags.QUESTRECORDEX; if (JobLogic.IsWildhunterJob(character.Stats.nJob)) { dbFlag |= DbCharFlags.WILDHUNTERINFO; } dbFlag |= DbCharFlags.MAPTRANSFER; c.SendPacket(CPacket.SetField(character, c.ChannelId, c.WorldID, Constants.LogoutGift, dbFlag)); } OnUserEnter(c.Character); if (bSendPartyMapChangeUpdate) { c.Character.NotifySocialChannels(SocialNotiflag.ChangeMap); } }