public static void DoHammer(MapleItem hammer, MapleEquip equip, MapleCharacter chr) { if (!CanHammer(equip)) { chr.SendPopUpMessage("You cannot use that on this item."); chr.EnableActions(); return; } switch (hammer.ItemId) { case 2470000: case 2470003: case 2470007: case 2470011: case 5570000: { equip.RemainingUpgradeCount++; equip.HammersApplied++; chr.Inventory.RemoveItemsFromSlot(hammer.InventoryType, hammer.Position, 1); chr.Client.SendPacket(MapleInventory.Packets.AddItem(equip, MapleInventoryType.Equip, equip.Position)); chr.Client.SendPacket(Packets.HammerEffect(true)); chr.Client.SendPacket(Packets.HammerResult(false, true, equip.HammersApplied)); PacketWriter finishPacket = Packets.HammerResult(true, true, 0); Scheduler.ScheduleDelayedAction(() => chr.Client.SendPacket(finishPacket), 1500); break; } default: { chr.SendPopUpMessage("You cannot use this hammer."); chr.EnableActions(); return; } } }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions(ActionState.NpcTalking)) { return; } try { int objectId = pr.ReadInt(); WzMap.Npc npc = chr.Map.GetNpc(objectId); if (npc == null) { ServerConsole.Warning("NPC is not on player {0}'s map: {1}", chr.Name, chr.Map.MapId); chr.EnableActions(); return; } NpcEngine.OpenNpc(npc.Id, objectId, c); } catch (Exception ex) { ServerConsole.Error("NpcChatHandler.Handle : " + ex); chr.EnableActions(); } }
public static void HandlePlayer(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } pr.Skip(1); try { int tickCount = pr.ReadInt(); Point position = pr.ReadPoint(); int objectId = pr.ReadInt(); if (position.DistanceTo(chr.Position) >= 50) { c.CheatTracker.AddOffence(AntiCheat.OffenceType.LootFarAwayItem); } bool success = chr.Map.HandlePlayerItemPickup(c, objectId); chr.EnableActions(!success); //Client doesn't need to be notified if it was succesful } catch { chr.EnableActions(); } }
public static void HandleRegularEquipScroll(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } //[BC E0 27 09] [09 00] [05 00] [01 00] [00] int tickCount = pr.ReadInt(); short useSlot = pr.ReadShort(); short equipSlot = pr.ReadShort(); short whiteScrollMask = pr.ReadShort(); bool whiteScroll = (whiteScrollMask & 0x2) > 0; //1 byte left, don't know what it is MapleEquip equip; MapleItem scroll; if (GetAndCheckItemsFromInventory(chr.Inventory, equipSlot, useSlot, out equip, out scroll)) { if (scroll.ItemType == MapleItemType.RegularEquipScroll) { MapleEquipEnhancer.UseRegularEquipScroll(chr, equip, scroll, whiteScroll); } } chr.EnableActions(false); }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (chr.ActionState != ActionState.Enabled) { return; } //chr.ActionState = ActionState.Disabled; int tickCount = pr.ReadInt(); chr.SendBlueMessage("The cash shop is disabled at this time, please go to the Free Market Entrance to buy Cash Items."); chr.EnableActions(); /* * PacketWriter pw = new PacketWriter(); * pw.WriteHeader(SendHeaders.ChangeChannel); * pw.WriteBool(true); * pw.WriteBytes(ServerConstants.NexonIp[3]); * pw.WriteShort(ServerConstants.CashShopPort); * pw.WriteByte(0); * * c.Account.MigrationData.ToChannel = 0xFF; * c.Account.MigrationData.ToCashShop = true; * c.Account.MigrationData.ReturnChannel = c.Channel; * c.Account.MigrationData.CheatTracker = c.CheatTracker; * c.Account.MigrationData.Character = c.Account.Character; * Program.EnqueueMigration(c.Account.MigrationData.CharacterId, c.Account.MigrationData); * c.Account.Character.ActionState = ActionState.Disabled; * * c.SendPacket(pw);*/ }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); int hammerSlot = pr.ReadInt(); int hammerItemId = pr.ReadInt(); MapleItem hammer = chr.Inventory.GetItemSlotFromInventory(MapleInventoryType.Use, (short)hammerSlot); if (hammer == null || hammer.ItemId != hammerItemId) { return; } pr.Skip(4); //Integer, inventory type? int equipSlot = pr.ReadInt(); MapleEquip equip = chr.Inventory.GetItemSlotFromInventory(MapleInventoryType.Equip, (short)equipSlot) as MapleEquip; if (equip == null) { return; } DoHammer(hammer, equip, chr); chr.EnableActions(false); }
public void Close(bool finished, bool success) //may be different for non-trade types like shops { Owner.Trade = null; if (Owner.Client != null) { Owner.Client.SendPacket(GenerateTradeClose(finished, success)); MapleInventory.UpdateMesos(Owner.Client, Owner.Inventory.Mesos); if (!success || !finished) { foreach (TradeItem item in items[0]) { if (item != null) { Owner.Client.SendPacket(MapleInventory.Packets.AddItem(item.Item, item.Item.InventoryType, item.Item.Position)); //force the "hidden" items to reappear } } Owner.EnableActions(); } else Owner.EnableActions(false); } foreach (MapleCharacter chr in Partners.Where(chr => chr.Trade == this)) { chr.Client.SendPacket(GenerateTradeClose(finished, success)); chr.Trade = null; MapleInventory.UpdateMesos(chr.Client, chr.Inventory.Mesos); if (Type == TradeType.Trade) { if (!success || !finished) { foreach (TradeItem item in items[1]) { if (item == null) continue; chr.Client.SendPacket(MapleInventory.Packets.AddItem(item.Item, item.Item.InventoryType, item.Item.Position)); } } } chr.EnableActions(false); } TradeIDs.Remove(TradeID); }
public static void EnterScriptedPortal(WzMap.Portal portal, MapleCharacter character) { if (!string.IsNullOrEmpty(portal.Script)) { Type portalScriptType; if (DataBuffer.PortalScripts.TryGetValue(portal.Script, out portalScriptType) && portalScriptType != null) { PortalScript scriptInstance = Activator.CreateInstance(portalScriptType) as PortalScript; if (scriptInstance == null) { string error = string.Format("Error loading {0} {1}", "PortalScript", portal.Script); ServerConsole.Error(error); FileLogging.Log("Portal scripts", error); return; } scriptInstance.Character = new ScriptCharacter(character, portal.Script); try { scriptInstance.Execute(); } catch (Exception e) { string error = string.Format("Script: {0} error: {1}", portal.Script, e); FileLogging.Log("Portal scripts", error); ServerConsole.Debug("Portal script execution error: " + error); character.EnableActions(); } } else { character.SendBlueMessage(string.Format("This portal is not coded yet (mapId: {0}, portalId: {1}, script name: {2})", character.MapId, portal.Id, portal.Script)); character.EnableActions(); } } else { character.EnableActions(); } }
public static void HandleReturnScroll(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); pr.Skip(2); //Unk int itemId = pr.ReadInt(); if (!chr.Inventory.HasItem(itemId)) { return; } WzConsume item = DataBuffer.GetItemById(itemId) as WzConsume; if (item == null) { return; } if (item.MoveTo > 0) { int toMap = 0; toMap = item.MoveTo == 999999999 ? chr.Map.ReturnMap : item.MoveTo; if (toMap != 0) { MapleMap map = Program.GetChannelServer(c.Channel).GetMap(toMap); if (map == null || map.PortalScrollLimit) { return; } if (chr.Inventory.RemoveItemsById(itemId, 1)) { chr.ChangeMap(toMap); } } } else { string msg = "Unhandled return scroll: " + itemId; ServerConsole.Warning(msg); FileLogging.Log("Unhandled items", msg); chr.EnableActions(); } }
public static void Handle(MapleClient c, PacketReader pw) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pw.ReadInt(); MapleInventoryType type = (MapleInventoryType)pw.ReadByte(); short oldPosition = pw.ReadShort(); short newPosition = pw.ReadShort(); short quantity = pw.ReadShort(); bool success = false; if (oldPosition == newPosition) { return; } try { MapleInventory inventory = chr.Inventory; if (newPosition < 0 && oldPosition > 0) //equip item { success = inventory.EquipItem(oldPosition, newPosition); } else if (oldPosition < 0 && newPosition > 0) //unequip item { success = inventory.UnEquip(oldPosition, newPosition); } else if (newPosition == 0) //drop item { if (!chr.Map.DropItemLimit) { success = inventory.DropItem(type, oldPosition, quantity); } } else //item moved within inventory { success = inventory.MoveItem(type, oldPosition, newPosition); } } finally { chr.EnableActions(!success); } }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (chr.ActionState == ActionState.Enabled) { int doorOwnerId = pr.ReadInt(); bool back = pr.ReadBool(); //return to source door if used in a town SpecialPortal door = chr.Map.GetDoor(doorOwnerId); if (door != null) { if (!door.IsPartyObject || (doorOwnerId == chr.Id || (chr.Party != null && chr.Party.Id == door.PartyId))) { door.Warp(chr); return; } } chr.EnableActions(); } }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); int skillId = pr.ReadInt(); byte skillLevel = pr.ReadByte(); if (skillId != Constants.Cleric.HEAL && skillId != Constants.Bishop.ANGEL_RAY) // Heal is already handled through MagicAttack { SkillEffect.CheckAndApplySkillEffect(c.Account.Character, skillId, DataBuffer.GetCharacterSkillById(skillId)); } else { chr.EnableActions(); } }
public static void HandlePotentialScroll(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); short useSlot = pr.ReadShort(); short equipSlot = pr.ReadShort(); MapleEquip equip; MapleItem scroll; if (GetAndCheckItemsFromInventory(chr.Inventory, equipSlot, useSlot, out equip, out scroll)) { MapleEquipEnhancer.UsePotentialScroll(equip, scroll, chr); } chr.EnableActions(false); }
public static void Handle(MapleClient c, PacketReader pw) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pw.ReadInt(); int mesos = pw.ReadInt(); if (mesos > 50000 || mesos < 10 || chr.Inventory.Mesos < mesos) { return; } chr.Inventory.RemoveMesos(mesos, false); Point targetPosition = chr.Map.GetDropPositionBelow(new Point(chr.Position.X, chr.Position.Y - 50), chr.Position); chr.Map.SpawnMesoMapItem(mesos, chr.Position, targetPosition, true, MapleDropType.Unk, chr); chr.EnableActions(false); }
public static void HandleItemSort(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); byte inventory = pr.ReadByte(); if (inventory < 1 || inventory > 5) { return; } MapleInventoryType type = (MapleInventoryType)inventory; chr.Inventory.SortItems(type, c); chr.EnableActions(false); c.SendPacket(Packets.ItemSortResponse(type)); }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (chr.Hp <= 0 || chr.ActionState == ActionState.Dead) { chr.Revive(true); return; } if (!chr.DisableActions()) { return; } if (pr.Available <= 0) { chr.EnableActions(); return; } pr.Skip(1); int targetMap = pr.ReadInt(); pr.Skip(4); string portalName = pr.ReadMapleString(); if (pr.Available >= 4) { int tickCount = pr.ReadInt(); } if (c.Account.Character.Map != null) { if (targetMap == -1) { c.Account.Character.Map.EnterPortal(c, portalName); } } }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; try { if (c.NpcEngine == null || c.NpcEngine.ScriptInstance == null) { if (chr.ActionState == ActionState.NpcTalking) { chr.EnableActions(); } return; } int objectId = c.NpcEngine.ScriptInstance.ObjectId; if (objectId != -1) //objectId == -1 when npc conversation was started by the server, so players can talk to NPCs that are not on their map (with commands etc) { WzMap.Npc npc = chr.Map.GetNpc(objectId); if (npc == null) { c.NpcEngine.ScriptInstance = null; return; } } byte type = pr.ReadByte(); byte next = pr.ReadByte(); if (next == 0xFF) //End Chat { c.NpcEngine.Dispose(); return; } if (next == 0 && (type != 2)) { c.NpcEngine.ScriptInstance.State -= 1; } else { c.NpcEngine.ScriptInstance.State += 1; } bool execute = false; switch (type) { case 0: //SendOk, SendPrev, SendNext execute = true; break; case 2: //SendYesNo execute = true; c.NpcEngine.ScriptInstance.Selection = next == 0 ? 0 : 1; break; case 3: //SendAskText if (next == 0) { execute = false; } else { execute = true; string text = pr.ReadMapleString(); c.NpcEngine.ScriptInstance.InText = text; } break; case 4: //SendGetNumber //Player.GetNpcStatus().Num = pr.ReadInt(); execute = true; break; case 5: //SendSimple if (next == 0) { execute = false; } else { if (pr.Available >= 4) { c.NpcEngine.ScriptInstance.Selection = pr.ReadInt(); //This can be int as well, decided by the client } else if (pr.Available >= 1) { c.NpcEngine.ScriptInstance.Selection = pr.ReadSByte(); } execute = true; } break; case 23: //Choose Job int choice = pr.ReadInt(); break; default: string msg = "Unknown Npc chat type: " + pr.ToString(); ServerConsole.Error(msg); FileLogging.Log("NPC chat type", msg); c.NpcEngine.ScriptInstance = null; break; } if (execute) { NpcEngine engine = c.NpcEngine; if (engine == null) { if (c.Account.Character.ActionState == ActionState.NpcTalking) { c.Account.Character.EnableActions(); } return; } engine.ExecuteScriptForNpc(); } else { c.NpcEngine.ScriptInstance = null; if (chr.ActionState == ActionState.NpcTalking) { chr.EnableActions(); } } } catch (Exception ex) { ServerConsole.Error("NpcChatMoreHandler.Handle : " + ex.ToString()); if (c.NpcEngine != null) { c.NpcEngine.ScriptInstance = null; } if (chr.ActionState == ActionState.NpcTalking) { chr.EnableActions(); } } }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); short magnifySlot = pr.ReadShort(); short equipSlot = pr.ReadShort(); MapleItem magnifyer = null; MapleEquip equip = c.Account.Character.Inventory.GetItemSlotFromInventory(MapleInventoryType.Equip, equipSlot) as MapleEquip; if (magnifySlot != 0x7F) // Using magnify button in inventory sends 0x007F as the slot { magnifyer = chr.Inventory.GetItemSlotFromInventory(MapleInventoryType.Use, magnifySlot); if (magnifyer == null) { return; //todo: check if it's a magnifying glass } } if (equip == null) { return; } WzEquip equipInfo = DataBuffer.GetEquipById(equip.ItemId); if (equipInfo == null) { return; } if (equip.PotentialState >= MaplePotentialState.HiddenRare && equip.PotentialState <= MaplePotentialState.HiddenLegendary) { long price = equipInfo.RevealPotentialCost; ServerConsole.Debug("pot cost: " + price); if (chr.Mesos < price) { chr.SendPopUpMessage(string.Format("You do not have {0} mesos", price)); chr.EnableActions(); } else { chr.Inventory.RemoveMesos(price); equip.PotentialState += 16; if (magnifyer != null) { chr.Inventory.RemoveItemsFromSlot(magnifyer.InventoryType, magnifyer.Position, 1); } c.SendPacket(MapleInventory.Packets.AddItem(equip, equip.InventoryType, equip.Position)); chr.Map.BroadcastPacket(MagnifyEffectPacket(chr.Id, equip.Position, true), chr, true); chr.EnableActions(false); } } else { chr.SendPopUpMessage("You cannot use that on this item"); chr.EnableActions(); } }
public static void HandleCube(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); short useSlot = pr.ReadShort(); short equipSlot = pr.ReadShort(); MapleEquip equip; MapleItem cube; if (GetAndCheckItemsFromInventory(chr.Inventory, equipSlot, useSlot, out equip, out cube)) { CubeType cubeType; switch (cube.ItemId) { //Occult: case 2710000: case 2711000: case 2710001: { cubeType = CubeType.Occult; break; } //Master craftsman: case 2710002: case 2710007: case 2711003: case 2711005: { cubeType = CubeType.MasterCraftsman; break; } //Meister: case 2710003: case 2711004: case 2711006: { cubeType = CubeType.Meister; break; } default: { chr.SendPopUpMessage("You cannot use this item"); chr.EnableActions(); return; } } if (MapleEquipEnhancer.CubeItem(equip, cubeType, chr)) { chr.Inventory.RemoveItemsFromSlot(MapleInventoryType.Use, cube.Position, 1); chr.EnableActions(false); } } }
public static void Handle(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } int tickCount = pr.ReadInt(); short slot = pr.ReadShort(); int itemId = pr.ReadInt(); MapleItem item = chr.Inventory.GetItemSlotFromInventory(ItemConstants.GetInventoryType(itemId), slot); bool removeItem = true; if (item == null || item.ItemId != itemId) { return; } switch (itemId) { case 5062006: //Platinum Miracle Cube { int equipSlot = pr.ReadInt(); if (equipSlot < 0) { return; } MapleEquip equip = chr.Inventory.GetItemSlotFromInventory(MapleInventoryType.Equip, (short)equipSlot) as MapleEquip; if (equip == null) { return; } if (!MapleEquipEnhancer.CubeItem(equip, CubeType.PlatinumMiracle, chr)) { removeItem = false; } break; } case 5072000: //Super Megaphone case 5072001: //Super Megaphone { if (!CanMegaPhone(c.Account.Character)) { chr.EnableActions(); break; } string message = pr.ReadMapleString(); if (message.Length > 60) { return; } bool whisperIcon = pr.ReadBool(); message = string.Format("{0} : {1}", c.Account.Character.Name, message); Program.BroadCastWorldPacket(MapleCharacter.ServerNotice(message, 3, c.Channel, whisperIcon)); break; } case 5570000: //Vicious hammer { removeItem = false; //Handled in UseGoldenHammerHandler pr.Skip(4); short equipSlot = (short)pr.ReadInt(); MapleEquip equip = chr.Inventory.GetItemSlotFromInventory(MapleInventoryType.Equip, equipSlot) as MapleEquip; if (equip != null) { UseGoldenHammerHandler.DoHammer(item, equip, chr); } break; } default: { ServerConsole.Warning("Unhandled UseSpecialItem: {0}", itemId); removeItem = false; chr.SendPopUpMessage("You cannot use this item"); chr.EnableActions(); break; } } if (removeItem) { chr.Inventory.RemoveItemsFromSlot(item.InventoryType, item.Position, 1); } chr.EnableActions(false); }
public static void Handle(MapleClient c, PacketReader pr) { int tickCount = pr.ReadInt(); short slot = pr.ReadShort(); int id = pr.ReadInt(); MapleCharacter chr = c.Account.Character; MapleItem item = chr.Inventory.GetItemSlotFromInventory(MapleInventoryType.Use, slot); if (item != null && item.ItemId == id) { WzConsume consume = DataBuffer.GetItemById(id) as WzConsume; if (consume != null) { chr.Inventory.RemoveItemsFromSlot(MapleInventoryType.Use, slot, 1, true); if (!chr.Map.PotionLimit) { if (consume.Hp != 0) { chr.AddHP((int)((chr.Stats.PotionEffectR / 100.0) * consume.Hp)); } if (consume.Mp != 0) { chr.AddMP((int)((chr.Stats.PotionEffectR / 100.0) * consume.Mp)); } if (consume.HpR != 0) { chr.AddHP((int)(chr.Stats.MaxHp * (consume.HpR / 100.0))); } if (consume.MpR != 0) { chr.AddMP((int)(chr.Stats.MaxMp * (consume.MpR / 100.0))); } } if (consume.MoveTo != 0 && !chr.Map.PortalScrollLimit) { chr.ChangeMap(consume.MoveTo); } if (consume.CharismaExp != 0) { chr.AddTraitExp(consume.CharismaExp, MapleCharacterStat.Charisma); } if (consume.CharmExp != 0) { chr.AddTraitExp(consume.CharmExp, MapleCharacterStat.Charm); } if (consume.CraftExp != 0) { chr.AddTraitExp(consume.CraftExp, MapleCharacterStat.Craft); } if (consume.InsightExp != 0) { chr.AddTraitExp(consume.InsightExp, MapleCharacterStat.Insight); } if (consume.SenseExp != 0) { chr.AddTraitExp(consume.SenseExp, MapleCharacterStat.Sense); } if (consume.WillExp != 0) { chr.AddTraitExp(consume.WillExp, MapleCharacterStat.Will); } return; } } chr.EnableActions(); }
public static void UseEquipEnhancementScroll(MapleEquip equip, MapleItem scroll, MapleCharacter chr) { if (equip == null || scroll == null) { return; } WzItemEnhancer wzScrollInfo = DataBuffer.GetItemById(scroll.ItemId) as WzItemEnhancer; WzEquip equipInfo = DataBuffer.GetEquipById(equip.ItemId); if (wzScrollInfo == null || equipInfo == null) { return; } int maxEnhancements; if (wzScrollInfo == null || equipInfo == null || (maxEnhancements = equipInfo.MaxStarEnhance) - equip.Enhancements < 1 || equip.RemainingUpgradeCount > 0) { chr.SendPopUpMessage("You cannot use that on this item."); chr.EnableActions(); return; } int chance; bool diminishChance = false; int enhancements; int curseChance = 100; switch (scroll.ItemId) { case 2049323: //advanced equip enhancement scroll curseChance = 0; goto case 2049300; case 2049300: case 2049303: case 2049306: case 2049325: { chance = 100; diminishChance = true; enhancements = 1; break; } case 2049301: //equip enhancement scroll case 2049307: { chance = 80; diminishChance = true; enhancements = 1; break; } default: { if (wzScrollInfo.StatEnhancements.TryGetValue("forceUpgrade", out enhancements) && //multiple star enhances wzScrollInfo.StatEnhancements.TryGetValue("success", out chance)) { if (!wzScrollInfo.StatEnhancements.TryGetValue("cursed", out curseChance)) { curseChance = 100; } break; } chr.SendPopUpMessage("This item is not coded, please report it on the forums. ItemId " + scroll.ItemId); ServerConsole.Debug("ItemID {0} is unhandled in UseEnhancementScroll", scroll.ItemId); return; } } bool scrollProtection = equip.CheckAndRemoveFlag(MapleItemFlags.ScrollProtection); bool curseProtection = equip.CheckAndRemoveFlag(MapleItemFlags.CurseProtection) && equip.Enhancements < 12; bool success = EnhanceEquip(equip, chance, diminishChance, enhancements, maxEnhancements); bool destroyed = false; byte scrollResult = 1; bool removeScroll = success || !scrollProtection; if (!success) { scrollResult = 0; if (!curseProtection && Functions.MakeChance(curseChance)) { scrollResult = 2; destroyed = true; } } if (removeScroll) { chr.Inventory.RemoveItemsFromSlot(scroll.InventoryType, scroll.Position, 1); } if (destroyed) { chr.Inventory.RemoveItem(equip.InventoryType, equip.Position); } else { chr.Client.SendPacket(MapleInventory.Packets.AddItem(equip, equip.InventoryType, equip.Position)); //Update item } chr.Map.BroadcastPacket(Packets.ShowScrollEffect(chr.Id, scrollResult, scroll.ItemId, equip.ItemId), chr, true); }
public static void Handle(MapleClient c, PacketReader packet) { MapleCharacter chr = c.Account.Character; if (!chr.DisableActions()) { return; } try { int tickCount = packet.ReadInt(); int skillId = packet.ReadInt(); byte amount = packet.ReadByte(); //new v137, multiple sp if (amount <= 0) { amount = 1; } short skillJobId = (short)(skillId / 10000); WzCharacterSkill wzSkill = DataBuffer.GetCharacterSkillById(skillId); if (wzSkill == null) { return; } if (wzSkill.IsGmSkill && !chr.IsStaff) { return; } if (!JobConstants.JobCanLearnSkill(skillId, chr.Job)) { return; } if (wzSkill.HasFixedLevel) { return; } if (chr.Level < wzSkill.RequiredLevel) { return; } if (wzSkill.RequiredSkills != null) { foreach (var kvp in wzSkill.RequiredSkills) { if (!chr.HasSkill(kvp.Key, kvp.Value)) { return; } } } if (wzSkill.IsHyperSkill) { chr.SendPopUpMessage("Hyper skills aren't functional yet."); chr.EnableActions(); return; } if (JobConstants.IsBeginnerJob(skillJobId)) { switch (skillId) { //Three snails: case Explorer.THREE_SNAILS: case Cygnus.THREE_SNAILS: case AranBasics.THREE_SNAILS: case EvanBasics.THREE_SNAILS: case MihileBasics.THREE_SNAILS: //Recovery: case Explorer.RECOVERY: case Cygnus.RECOVERY: case AranBasics.RECOVERY: case EvanBasics.RECOVER: case MihileBasics.RECOVERY: //Nimble Feet: case Explorer.NIMBLE_FEET: case Cygnus.NIMBLE_FEET: case AranBasics.AGILE_BODY: case EvanBasics.NIMBLE_FEET: case MihileBasics.NIMBLE_FEET: //Resistance: case Resistance.POTION_MASTERY: case Resistance.INFILTRATE: case Resistance.CRYSTAL_THROW: if (chr.GetSkillLevel(skillId) + amount > 3) //already maxed { return; } int baseNum = 0; switch (skillId / 100000) { case 300: //resistance { if (!chr.IsResistance) { return; } int usedBeginnerSP = chr.GetSkillLevel(Resistance.CRYSTAL_THROW) + chr.GetSkillLevel(Resistance.INFILTRATE) + chr.GetSkillLevel(Resistance.POTION_MASTERY); if (usedBeginnerSP + amount <= 9 && chr.GetSkillLevel(skillId) + amount <= 3) { chr.IncreaseSkillLevel(skillId, amount); } break; } case 0: if (!chr.IsExplorer) { return; } goto common; case 100: //cygnus if (!chr.IsCygnus) { return; } baseNum = 10000000; goto common; case 200: //hero if (!chr.IsAran && !chr.IsEvan) { return; } baseNum = 20000000; goto common; case 500: //mihile if (!chr.IsMihile) { return; } baseNum = 50000000; common: { int usedBeginnerSP = chr.GetSkillLevel(baseNum + 1000) + chr.GetSkillLevel(baseNum + 1001) + chr.GetSkillLevel(baseNum + 1002); if (usedBeginnerSP + amount <= 6 && chr.GetSkillLevel(skillId) + amount <= 3) { chr.IncreaseSkillLevel(skillId, amount); } break; } default: return; } break; default: return; } } else { int spTableIndex = JobConstants.GetSkillBookForJob(skillJobId); if (chr.SpTable[spTableIndex] >= amount) { Skill skill = chr.GetSkill(skillId); if (skill == null) //Player doesnt have the skill yet { int maxLevel = wzSkill.HasMastery ? wzSkill.DefaultMastery : wzSkill.MaxLevel; if (amount <= maxLevel) { chr.LearnSkill(skillId, amount, wzSkill); chr.SpTable[spTableIndex] -= amount; MapleCharacter.UpdateSingleStat(c, MapleCharacterStat.Sp, chr.SpTable[0], true); } } else { if (skill.Level + amount <= skill.MasterLevel) { chr.IncreaseSkillLevel(skillId, amount); chr.SpTable[spTableIndex] -= amount; MapleCharacter.UpdateSingleStat(c, MapleCharacterStat.Sp, chr.SpTable[0], true); } } } } } finally { chr.EnableActions(false); } }
public static bool UseBonusPotentialScroll(MapleEquip equip, MapleItem scroll, MapleCharacter chr) { if (equip.PotentialState == MaplePotentialState.None) { return(false); //Can only be used on items that already have regular potential } int successChance; int curseChance; switch (scroll.ItemId) { case 2048305: { successChance = 70; curseChance = 100; break; } case 2048308: case 2048311: { successChance = 50; curseChance = 50; break; } case 2048309: case 2048314: { successChance = 60; curseChance = 0; break; } case 2048310: { successChance = 60; curseChance = 100; break; } case 2048307: case 2048315: case 2048329: { successChance = 100; curseChance = 0; break; } default: { chr.SendPopUpMessage("You cannot use this item."); chr.EnableActions(); return(false); } } if (equip.CheckAndRemoveFlag(MapleItemFlags.LuckyDay)) { successChance += 10; } bool destroyed = false; bool removeScroll = true; bool scrollProtection = equip.CheckAndRemoveFlag(MapleItemFlags.ScrollProtection); bool curseProtection = curseChance > 0 && equip.CheckAndRemoveFlag(MapleItemFlags.CurseProtection); byte scrollResult; if (Functions.MakeChance(successChance)) { scrollResult = 1; AddRandomBonusPotential(equip); } else { scrollResult = 0; destroyed = !curseProtection && Functions.MakeChance(curseChance); removeScroll = !scrollProtection; } if (removeScroll) { chr.Inventory.RemoveItemsFromSlot(scroll.InventoryType, scroll.Position, 1); } if (destroyed) { chr.Inventory.RemoveItem(equip.InventoryType, equip.Position); scrollResult = 2; } else { chr.Client.SendPacket(MapleInventory.Packets.AddItem(equip, equip.InventoryType, equip.Position)); //Update item stats } chr.Map.BroadcastPacket(Packets.ShowScrollEffect(chr.Id, scrollResult, scroll.ItemId, equip.ItemId), chr, true); return(true); }
public static bool UsePotentialScroll(MapleEquip equip, MapleItem scroll, MapleCharacter chr) { int successChance; int curseChance = 0; MaplePotentialState grade = MaplePotentialState.Rare; switch (scroll.ItemId) { //Potential scrolls: case 2049401: case 2049408: { successChance = 70; curseChance = 100; break; } case 2049416: { successChance = 70; break; } case 2049400: case 2049407: case 2049412: case 2049413: { successChance = 90; curseChance = 100; break; } case 2049402: case 2049417: case 2049406: { successChance = 100; break; } //Epic potential scrolls: case 2049700: //case 2049702: ? case 2049703: case 2049706: { successChance = 100; grade = MaplePotentialState.Epic; break; } case 2049702: { successChance = 80; curseChance = 20; grade = MaplePotentialState.Epic; break; } case 2049704: case 2049707: { successChance = 40; grade = MaplePotentialState.Epic; break; } case 2049709: { curseChance = 50; goto case 2049705; } case 2049705: case 2049708: case 2049710: { successChance = 50; grade = MaplePotentialState.Epic; break; } //Unique potential scrolls: case 2049750: case 2049753: { successChance = 80; grade = MaplePotentialState.Unique; break; } case 2049751: case 2049754: { successChance = 60; grade = MaplePotentialState.Unique; break; } case 2049757: case 2049758: { successChance = 50; grade = MaplePotentialState.Unique; break; } case 2049752: case 2049755: case 2049756: { successChance = 30; grade = MaplePotentialState.Unique; break; } default: { chr.SendPopUpMessage("You cannot use this item"); chr.EnableActions(); return(false); } } //Item has potential but it's hidden or is same rank as the potential given by the scroll if (equip.PotentialState != MaplePotentialState.None && (equip.PotentialState < MaplePotentialState.Rare || equip.PotentialState >= grade)) { return(false); } if (equip.CheckAndRemoveFlag(MapleItemFlags.LuckyDay)) { successChance += 10; } bool destroyed = false; bool removeScroll = true; bool scrollProtection = equip.CheckAndRemoveFlag(MapleItemFlags.ScrollProtection); bool curseProtection = curseChance > 0 && equip.CheckAndRemoveFlag(MapleItemFlags.CurseProtection); byte scrollResult; if (Functions.MakeChance(successChance)) { scrollResult = 1; AddRandomPotential(equip); } else { scrollResult = 0; destroyed = !curseProtection && Functions.MakeChance(curseChance); removeScroll = !scrollProtection; } if (removeScroll) { chr.Inventory.RemoveItemsFromSlot(scroll.InventoryType, scroll.Position, 1); } if (destroyed) { chr.Inventory.RemoveItem(equip.InventoryType, equip.Position); scrollResult = 2; } else { chr.Client.SendPacket(MapleInventory.Packets.AddItem(equip, equip.InventoryType, equip.Position)); //Update item stats } chr.Map.BroadcastPacket(Packets.ShowScrollEffect(chr.Id, scrollResult, scroll.ItemId, equip.ItemId), chr, true); return(true); }
public static void UseRegularEquipScroll(MapleCharacter chr, MapleEquip equip, MapleItem scroll, bool whiteScroll) { WzItemEnhancer scrollInfo = DataBuffer.GetItemById(scroll.ItemId) as WzItemEnhancer; if (scrollInfo == null) { return; } WzEquip equipInfo = DataBuffer.GetEquipById(equip.ItemId); string reason = ""; if (equipInfo == null || !CanScroll(equip, equipInfo, scrollInfo, out reason)) { chr.SendPopUpMessage("You cannot use that scroll on this item. " + reason); chr.EnableActions(); return; } byte upgradeSlotsUsed = 1; int scrollBaseId = scroll.ItemId / 100; if (scrollBaseId == 20490 || //clean slate scroll scrollBaseId == 20493 || //equip enhancement scroll scrollBaseId == 20496) //innocence scroll { upgradeSlotsUsed = 0; } switch (scroll.ItemId) { case 2040727: //Scroll for Spikes on Shoes case 2041058: //Scroll for Cape for Cold Protection upgradeSlotsUsed = 0; break; } int value; if (scrollInfo.StatEnhancements.TryGetValue("tuc", out value)) //Uses multiple upgrade slots { upgradeSlotsUsed = (byte)value; } if (equip.RemainingUpgradeCount < upgradeSlotsUsed) { chr.SendPopUpMessage(string.Format("This item does not have enough upgrades available")); chr.EnableActions(); return; } byte scrollResult = 0; bool destroyed = false; bool removeScroll = true; int chance = scrollInfo.Chance; bool scrollProtection = equip.CheckAndRemoveFlag(MapleItemFlags.ScrollProtection); bool upgradeCountProtection = upgradeSlotsUsed > 0 && equip.CheckAndRemoveFlag(MapleItemFlags.UpgradeCountProtection); bool curseProtection = equip.CheckAndRemoveFlag(MapleItemFlags.CurseProtection); if (equip.CheckAndRemoveFlag(MapleItemFlags.LuckyDay)) { chance += 10; } if (Functions.MakeChance(chance)) { scrollResult = 1; equip.UpgradeCount += upgradeSlotsUsed; foreach (var kvp in scrollInfo.StatEnhancements) { switch (kvp.Key) { case "incPDD": equip.Pdd += (short)kvp.Value; break; case "incMDD": equip.Mdd += (short)kvp.Value; break; case "incACC": equip.Acc += (short)kvp.Value; break; case "incMHP": equip.IncMhp += (short)kvp.Value; break; case "incINT": equip.Int += (short)kvp.Value; break; case "incDEX": equip.Dex += (short)kvp.Value; break; case "incMAD": equip.Mad += (short)kvp.Value; break; case "incPAD": equip.Pad += (short)kvp.Value; break; case "incEVA": equip.Eva += (short)kvp.Value; break; case "incLUK": equip.Luk += (short)kvp.Value; break; case "incMMP": equip.IncMmp += (short)kvp.Value; break; case "incSTR": equip.Str += (short)kvp.Value; break; case "incSpeed": equip.Speed += (short)kvp.Value; break; case "incJump": equip.Jump += (short)kvp.Value; break; case "incCraft": equip.Diligence += (short)kvp.Value; break; case "preventslip": equip.Flags |= MapleItemFlags.NoSlip; break; case "warmsupport": equip.Flags |= MapleItemFlags.ColdResistance; break; case "recover": { int totalPossibleUpgrades = equipInfo.TotalUpgradeCount + equip.HammersApplied; int failedUpgrades = totalPossibleUpgrades - equip.UpgradeCount - equip.RemainingUpgradeCount; int toRestore = Math.Min(failedUpgrades, kvp.Value); if (toRestore > 0) { equip.RemainingUpgradeCount += (byte)toRestore; } break; } case "randstat": //chaos scroll { bool betterStats = scrollInfo.StatEnhancements.ContainsKey("incRandVol"); bool noNegative = scrollInfo.StatEnhancements.ContainsKey("noNegative"); if (equip.Str > 0) { equip.Str = GetNewChaosStat(equip.Str, betterStats, noNegative); } if (equip.Dex > 0) { equip.Dex = GetNewChaosStat(equip.Dex, betterStats, noNegative); } if (equip.Int > 0) { equip.Int = GetNewChaosStat(equip.Int, betterStats, noNegative); } if (equip.Luk > 0) { equip.Luk = GetNewChaosStat(equip.Luk, betterStats, noNegative); } if (equip.Pad > 0) { equip.Pad = GetNewChaosStat(equip.Pad, betterStats, noNegative); } if (equip.Mad > 0) { equip.Mad = GetNewChaosStat(equip.Mad, betterStats, noNegative); } if (equip.Pdd > 0) { equip.Pdd = GetNewChaosStat(equip.Pdd, betterStats, noNegative); } if (equip.Mdd > 0) { equip.Mdd = GetNewChaosStat(equip.Mdd, betterStats, noNegative); } if (equip.Acc > 0) { equip.Acc = GetNewChaosStat(equip.Acc, betterStats, noNegative); } if (equip.Eva > 0) { equip.Eva = GetNewChaosStat(equip.Eva, betterStats, noNegative); } if (equip.Speed > 0) { equip.Speed = GetNewChaosStat(equip.Speed, betterStats, noNegative); } if (equip.Jump > 0) { equip.Jump = GetNewChaosStat(equip.Jump, betterStats, noNegative); } if (equip.IncMhp > 0) { equip.IncMhp = GetNewChaosStat(equip.IncMhp, betterStats, noNegative); } if (equip.IncMmp > 0) { equip.IncMmp = GetNewChaosStat(equip.IncMmp, betterStats, noNegative); } break; } case "reset": { equip.SetDefaultStats(equipInfo, true); break; } case "perfectReset": { equip.SetDefaultStats(equipInfo); break; } } equip.SaveToDatabase(chr); } } else //Fail { int cursedChance; if (scrollInfo.StatEnhancements.TryGetValue("cursed", out cursedChance)) { destroyed = !curseProtection && Functions.MakeChance(cursedChance); } if (scrollProtection) { removeScroll = false; } if (upgradeCountProtection) { upgradeSlotsUsed = 0; } //todo: white scroll } equip.RemainingUpgradeCount -= upgradeSlotsUsed; if (removeScroll) { chr.Inventory.RemoveItemsFromSlot(scroll.InventoryType, scroll.Position, 1); } if (destroyed) { chr.Inventory.RemoveItem(equip.InventoryType, equip.Position); scrollResult = 2; } else { chr.Client.SendPacket(MapleInventory.Packets.AddItem(equip, equip.InventoryType, equip.Position)); //Update item stats } chr.Map.BroadcastPacket(Packets.ShowScrollEffect(chr.Id, scrollResult, scroll.ItemId, equip.ItemId), chr, true); }