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 EventEngine(MapleCharacter starter, string script, int recreateMap = -1, bool skipSpawn = false) { Starter = starter; ChannelId = Starter.Client.Channel; if (!(DataBuffer.EventScripts.TryGetValue(script, out EventType) && EventType != null)) { return; } EventInstance = ScriptActivator.CreateScriptInstance(EventType, script, starter) as EventScript; if (EventInstance == null) { string error = string.Format("Error loading {0} {1}", "EventScript", script); ServerConsole.Error(error); FileLogging.Log("Event scripts", error); return; } RecreatedMap = recreateMap != -1; EventInstance.OnFinish += new Action(FinishEvent); EventInstance.OnSpawnMobs += new Action <int, int, int, int>(SpawnMobs); EventInstance.OnRandomSpawnMobs += new Action <int, int, Point, Point>(RandomSpawnMobs); if (RecreatedMap) { EventMap = new MapleEvent(recreateMap, DataBuffer.GetMapById(recreateMap), skipSpawn); EventId = Program.RegisterEvent(EventMap); if (Starter != null) { AddCharacter(Starter); } } }
private void OnNewClientConnect(IAsyncResult iar) { if (Disposed) { return; } Socket clientsocket; try { clientsocket = Listener.EndAcceptSocket(iar); } catch (Exception e) { if (!Disposed) { Listener.BeginAcceptSocket(OnNewClientConnect, null); } ServerConsole.Error(String.Format("EndAccept Server Error: {0}", e)); return; //Intentional, we have to scap this connection but still let the listener survive. } try { Listener.BeginAcceptSocket(OnNewClientConnect, null); if (OnClientConnected != null) { OnClientConnected(clientsocket); } } catch (Exception ex) { ServerConsole.Error(String.Format("Server Error: {0}", ex)); } }
public void ApplyBuffEffect(MapleCharacter target) { if (Parent.SkillId == Priest.HOLY_MAGIC_SHELL && target.HasSkillOnCooldown(Priest.HOLY_MAGIC_SHELL + 1000)) { return; } int time; if (Info.TryGetValue(CharacterSkillStat.time, out time)) { ulong ltime = 1000 * (ulong)time; if (ltime >= int.MaxValue) { ltime = MAX_BUFF_TIME_MS; } uint uTime = (uint)Math.Min(((target.Stats.BuffTimeR / 100.0) * ltime), SkillEffect.MAX_BUFF_TIME_MS); Buff buff = new Buff(Parent.SkillId, this, uTime, target, DateTime.UtcNow); target.GiveBuff(buff); } else { ServerConsole.Error("Buff from skill " + Parent.SkillId + " has no buff time"); } }
public void SetDefaultStats(WzEquip info, bool randomizeStats = false, bool addRandomPotential = false) { UpgradeCount = 0; Enhancements = 0; Diligence = 0; CustomLevel = 0; CustomExp = 0; HammersApplied = 0; if (info != null) { RemainingUpgradeCount = info.TotalUpgradeCount; if (randomizeStats) { Str = GetRandomizedStat(info.IncStr); Int = GetRandomizedStat(info.IncInt); Dex = GetRandomizedStat(info.IncDex); Luk = GetRandomizedStat(info.IncLuk); IncMhp = GetRandomizedStat(info.IncMhp); IncMmp = GetRandomizedStat(info.IncMmp); Pad = GetRandomizedStat(info.IncPad); Mad = GetRandomizedStat(info.IncMad); Pdd = GetRandomizedStat(info.IncPdd); Mdd = GetRandomizedStat(info.IncMdd); Acc = GetRandomizedStat(info.IncAcc); Eva = GetRandomizedStat(info.IncEva); Speed = GetRandomizedStat(info.IncSpeed); Jump = GetRandomizedStat(info.IncJump); } else { Str = info.IncStr; Int = info.IncInt; Dex = info.IncDex; Luk = info.IncLuk; IncMhp = info.IncMhp; IncMmp = info.IncMmp; Pad = info.IncPad; Mad = info.IncMad; Pdd = info.IncPdd; Mdd = info.IncMdd; Acc = info.IncAcc; Eva = info.IncEva; Speed = info.IncSpeed; Jump = info.IncJump; } if (addRandomPotential) //todo: check if this equip can have potential { MapleEquipEnhancer.AddRandomPotential(this, equipInfo: info); } } else { ServerConsole.Error("Equip id {0} not in Data Buffer!", ItemId); } }
internal void RecvPacket(PacketReader packet) { try { RecvPacketHandler.Handle(packet, this); } catch (Exception e) { ServerConsole.Error(e.ToString()); FileLogging.Log("PacketExceptions.txt", e.ToString()); } }
public static void Handle(MapleClient c, PacketReader pr) { try { if (c.Account == null) { c.Disconnect("Client is not logged in to an account"); return; } string pic = pr.ReadMapleString(); int characterId = pr.ReadInt(); pr.Skip(1); string macs = pr.ReadMapleString(); string clientid = pr.ReadMapleString(); if (c.Account.CheckPic(pic) && c.Account.HasCharacter(characterId) && Program.ChannelServers.ContainsKey(c.Channel)) { ushort port = Program.ChannelServers[c.Channel].Port; c.Account.MigrationData.CharacterId = characterId; c.Account.MigrationData.Character = MapleCharacter.LoadFromDatabase(characterId, false); c.Account.MigrationData.Character.Hidden = c.Account.IsGM; Program.EnqueueMigration(characterId, c.Account.MigrationData); c.SendPacket(ChannelIpPacket(port, characterId)); } else { //Incorrect Pic PacketWriter pw = new PacketWriter(); pw.WriteHeader(SendHeader.PICResponse); pw.WriteByte(0x14); c.SendPacket(pw); } } catch (Exception ex) { ServerConsole.Error(ex.ToString()); FileLogging.Log("Character loading", ex.ToString()); c.SendPacket(MapleCharacter.ServerNotice("Error loading character", 1)); /*PacketWriter pw = new PacketWriter(); * pw.WriteHeader(SendHeaders.PICResponse); * pw.WriteByte(0x15); * c.SendPacket(pw);*/ } }
/// <summary> /// Creates a new instance of parameter scriptType as a Script object /// </summary> /// <param name="scriptType">The type of the script to be instantialized</param> /// <param name="scriptName">The name of the script</param> /// <param name="chr">The character that triggered the creation of the script</param> /// <returns>The created Script instance</returns> public static Script CreateScriptInstance(Type scriptType, string scriptName, MapleCharacter chr) { var instance = Activator.CreateInstance(scriptType) as Script; if (instance == null) { ServerConsole.Error(string.Format("Type {0} cannot be cast to 'Script'", scriptType)); return(null); } if (instance is CharacterScript) { CharacterScript cInstance = (CharacterScript)instance; cInstance.Character = new ScriptCharacter(chr, scriptName); } instance.DataProvider = ScriptDataProvider; return(instance); }
public void AcceptTrade(MapleCharacter chr) { if (Type != TradeType.Trade) return; if (Partners.Count == 1 && chr == Owner) { OwnerAccepted = true; Partners[0].Client.SendPacket(GenerateTradeAccepted()); } else if (Partners.Count == 1 && chr == Partners[0]) { PartnerAccepted = true; Owner.Client.SendPacket(GenerateTradeAccepted()); } else { ServerConsole.Error("Unable to accept trade because this character isn't registered as in the trade. Partner count " + Partners.Count); return; } if (OwnerAccepted && PartnerAccepted) { TradeItem[] ownersItems = items[0]; TradeItem[] partnersItems = items[1]; MapleCharacter partner = Partners[0]; MapleCharacter owner = Owner; if (OwnerMesos + partner.Inventory.Mesos <= GameConstants.MAX_MESOS && PartnerMesos + owner.Inventory.Mesos <= GameConstants.MAX_MESOS && CanTransferItems(ownersItems, partner) && CanTransferItems(partnersItems, owner)) { Close(true, true); TransferItems(ownersItems, owner, partner); TransferItems(partnersItems, partner, owner); Owner.Inventory.RemoveMesos(OwnerMesos, false); partner.Inventory.RemoveMesos(PartnerMesos, false); Owner.Inventory.GainMesos(PartnerMesos, false); partner.Inventory.GainMesos(OwnerMesos, false); } else //Items cant be transfered { Close(true, false); } } }
public BoundingBox CalculateBoundingBox(Point origin, bool facingLeft) { int range; if (Info.TryGetValue(CharacterSkillStat.range, out range)) { if (facingLeft) { return(new BoundingBox(origin.X - range, origin.Y - 100, origin.X, origin.Y)); } else { return(new BoundingBox(origin.X, origin.Y - 100, origin.X + range, origin.Y)); } } else { ServerConsole.Error("Skill " + Parent.SkillId + " is a Party ability but has no bounding box or range attributes"); } return(new BoundingBox()); }
public NpcEngine(MapleClient c, int id) { Client = c; NpcId = id; Type npcT; if (DataBuffer.NpcScripts.TryGetValue(NpcId, out npcT) && npcT != null) { ScriptInstance = ScriptActivator.CreateScriptInstance(npcT, npcT.ToString(), c.Account.Character) as NpcScript; if (ScriptInstance == null) { string error = string.Format("Error loading {0} {1}", "NpcScript", npcT.ToString()); ServerConsole.Error(error); FileLogging.Log("Npc scripts", error); return; } if (ScriptInstance.IsShop) { IsShop = true; } else { ScriptInstance.SendOk = new Action <string>(SendOk); ScriptInstance.SendNext = new Action <string>(SendNext); ScriptInstance.SendPrev = new Action <string>(SendPrev); ScriptInstance.SendNextPrev = new Action <string>(SendNextPrev); ScriptInstance.SendSimple = new Action <string>(SendSimple); ScriptInstance.EndChat = new Action(Dispose); ScriptInstance.SendYesNo = new Action <string>(SendYesNo); ScriptInstance.SendAskText = new Action <string, int, int, string>(SendAskText); } } else { SendOk(string.Format(@"An error has occured in my script. Please report this as a bug\r\nNpcId: {0}", NpcId)); ServerConsole.Debug(string.Format(@"Missing script for NPC: {0}", NpcId)); ScriptInstance = null; c.Account.Character.EnableActions(); } }
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 bool IsValidCharacter(JobType type, byte gender, int hair, int face, Dictionary <MapleEquipPosition, int> equips, int hairColor, int skinColor, int demonMark, int tamerEars, int tamerTail) { if (!IsValidId(type, gender, face, 0) || !IsValidId(type, gender, hair, 1)) { return(false); } try { switch (type) { case JobType.Explorer: case JobType.DualBlade: case JobType.Cannonneer: case JobType.Cygnus: if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5)) { return(false); } break; case JobType.Resistance: case JobType.Aran: case JobType.Evan: if (!IsValidId(type, gender, hairColor, 2) || !IsValidId(type, gender, skinColor, 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Bottom], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7)) { return(false); } break; case JobType.Jett: if (!IsValidId(type, gender, equips[MapleEquipPosition.Top], 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Cape], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5)) { return(false); } break; case JobType.Mercedes: if (!IsValidId(type, gender, equips[MapleEquipPosition.Top], 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 4)) { return(false); } break; case JobType.Phantom: case JobType.Luminous: if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Cape], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 6)) { return(false); } break; case JobType.Demon: if (!IsValidId(type, gender, demonMark, 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.SecondWeapon], 6)) { return(false); } break; case JobType.Xenon: if (!IsValidId(type, gender, hairColor, 2) || !IsValidId(type, gender, skinColor, 3) || !IsValidId(type, gender, demonMark, 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7)) { return(false); } break; case JobType.Hayato: case JobType.Kanna: if (!IsValidId(type, gender, hairColor, 2) || !IsValidId(type, gender, skinColor, 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Hat], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7)) { return(false); } break; case JobType.Mihile: if (!IsValidId(type, gender, skinColor, 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Bottom], 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 7)) { return(false); } break; case JobType.Kaiser: case JobType.AngelicBuster: if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 3) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 4) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 5)) { return(false); } break; case JobType.BeastTamer: if (!IsValidId(type, gender, skinColor, 2) || !IsValidId(type, gender, demonMark, 3) || !IsValidId(type, gender, tamerEars, 4) || !IsValidId(type, gender, tamerTail, 5) || !IsValidId(type, gender, equips[MapleEquipPosition.Top], 6) || !IsValidId(type, gender, equips[MapleEquipPosition.Shoes], 7) || !IsValidId(type, gender, equips[MapleEquipPosition.Weapon], 8)) { return(false); } break; default: ServerConsole.Error("Could not validate newly created character because job " + type + " is not handled"); return(false); } } catch { return(false); } return(true); }
public static void Handle(MapleClient c, PacketReader pr) { //6800 29939E7B 81BFD40F FD 00 60000000 00 00 037B 00 //6800 418AE151 6BE4D40F FF 00 01000000 00 00 47357C00 FE77AD00 00 00000000 00000000 00 00 00 //C101 CA566800 FD 60000000 00 60000000 //C101 68EB7A00 FF 01000000 00 F6761200 00 00000000 00000000 00 00 01000000 //effect //CD01 CA566800 [000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200] 0100 7B000300 00 00 00 00000000 00000000 00000000 00000000 00000000 0000 MapleCharacter chr = c.Account.Character; if (chr.Hidden) { return; } pr.Skip(4); //rnd num pr.Skip(4); //tickcount byte type = pr.ReadByte(); int damage = 0; pr.ReadByte(); damage = pr.ReadInt(); pr.Skip(2); int fake = 0; if (damage == -1) { fake = 4020002 + (chr.Job / 10 - 40) * 100000; if ((fake != NightLord.SHADOW_SHIFTER) && (fake != Shadower.SHADOW_SHIFTER)) { fake = NightLord.SHADOW_SHIFTER; } } switch (type) { case 0xFF: //mob damage { int mobid = pr.ReadInt(); int oid = pr.ReadInt(); MapleMonster mob = chr.Map.GetMob(oid); if (mob == null) { return; } byte direction = pr.ReadByte(); int skillid = pr.ReadInt(); int pDmg = pr.ReadInt(); byte defType = pr.ReadByte(); bool pPhysical = false; int pId = 0; byte pType = 0; Point pPos = Point.Empty; pr.ReadByte(); if (skillid != 0) { pPhysical = pr.ReadBool(); pId = pr.ReadInt(); pType = pr.ReadByte(); pr.Skip(4); pPos = pr.ReadPoint(); } byte offset = 0; int offsetD = 0; if (pr.Available == 1L) { offset = pr.ReadByte(); if ((offset == 1) && (pr.Available >= 4L)) { offsetD = pr.ReadInt(); } if ((offset < 0) || (offset > 2)) { offset = 0; } } BroadcastDamagePlayerPacket(chr, type, damage, mobid, direction, skillid, pDmg, pPhysical, pId, pType, pPos, offset, offsetD, fake); damage = DoMonsterDamageModifiers(damage, chr, mob, oid); if (damage > 0) { chr.AddHP(-damage); } } break; case 0xFD: //no mob, such as fall damage { short skill = pr.ReadShort(); //skill pr.ReadByte(); //? byte offset = 0; int offsetD = 0; if (pr.Available >= 1) { offset = pr.ReadByte(); if ((offset == 1) && (pr.Available >= 4)) { offsetD = pr.ReadInt(); } if ((sbyte)offset < 0 || offset > 2) { offset = 0; } } BroadcastDamagePlayerPacket(chr, type, damage, 0, 0, 0, 0, false, 0, 0, System.Drawing.Point.Empty, offset, offsetD, fake); if (damage > 0) { chr.AddHP(-damage); } } break; default: ServerConsole.Error("Invalid CharacterReceiveDamage type {0} ", type); break; } }
public static short GetJobIdByJobType(JobType jobType) { switch (jobType) { case JobType.Ultimate: case JobType.Explorer: case JobType.Cannonneer: case JobType.Jett: case JobType.DualBlade: return(0); case JobType.Cygnus: return(1000); case JobType.Aran: return(2000); case JobType.Evan: return(2001); case JobType.Mercedes: return(2002); case JobType.Phantom: return(2003); case JobType.Luminous: return(2004); case JobType.Resistance: return(3000); case JobType.Demon: return(3001); case JobType.Xenon: return(3002); case JobType.Hayato: return(4001); case JobType.Kanna: return(4002); case JobType.Mihile: return(5000); case JobType.Kaiser: return(6000); case JobType.AngelicBuster: return(6001); case JobType.Zero: return(10000); case JobType.BeastTamer: return(11000); default: ServerConsole.Error(String.Format("Unhandled JobType: {0} in CreateCharHandler", jobType)); return(0); } }
public static void Handle(MapleClient c, PacketReader pr) { try { if (c.NpcEngine != null && c.NpcEngine.IsShop) { byte mode = pr.ReadByte(); int NpcId = c.NpcEngine.NpcId; switch (mode) { case 0: { short shopIndex = pr.ReadShort(); int itemId = pr.ReadInt(); short amount = pr.ReadShort(); c.NpcEngine.BuyItem(itemId, shopIndex, amount); break; } case 1: //sell { short inventoryIndex = pr.ReadShort(); int itemId = pr.ReadInt(); short qty = pr.ReadShort(); MapleInventoryType invType = ItemConstants.GetInventoryType(itemId); switch (invType) { case MapleInventoryType.Equip: case MapleInventoryType.Etc: case MapleInventoryType.Setup: case MapleInventoryType.Use: break; default: return; // Not a valid item } WzItem wzitem = DataBuffer.GetItemById(itemId); if (wzitem == null) { wzitem = DataBuffer.GetEquipById(itemId); } if (wzitem == null) // Item doesnt exist (anymore?) { return; } if (wzitem.NotSale || wzitem.IsCashItem || wzitem.IsQuestItem) { return; } byte response = 0; if (!wzitem.IsQuestItem) { MapleInventory inventory = c.Account.Character.Inventory; MapleItem item = inventory.GetItemSlotFromInventory(invType, inventoryIndex); if (item?.ItemId == itemId && item.Quantity >= qty) { if (inventory.Mesos + wzitem.Price > GameConstants.MAX_MESOS) { response = 2; // You do not have enough mesos } else { inventory.RemoveItemsFromSlot(item.InventoryType, item.Position, qty, true); inventory.GainMesos(wzitem.Price * qty, false, false); } // TODO: buyback } } PacketWriter pw = new PacketWriter(); pw.WriteHeader(SendHeader.NpcTransaction); pw.WriteByte(response); pw.WriteByte(0); pw.WriteByte(0); c.SendPacket(pw); break; } case 3: { c.NpcEngine.Dispose(); break; } default: { c.NpcEngine.ScriptInstance = null; ServerConsole.Warning("Unkown NpcShopActionHandler mode:" + mode); ServerConsole.Info(Functions.ByteArrayToStr(pr.ToArray())); break; } } } } catch (Exception ex) { ServerConsole.Error("NpcShopActionHandler Failure"); ServerConsole.Error(ex.Message); if (c.NpcEngine != null) { c.NpcEngine.Dispose(); } } }
public static void HandleDistribute(MapleClient c, PacketReader pr) { MapleCharacter chr = c.Account.Character; if (chr.AP == 0) { return; } int tickCount = pr.ReadInt(); int statsCount = pr.ReadInt(); Dictionary <MapleCharacterStat, long> statsAssign = new Dictionary <MapleCharacterStat, long>(); for (int i = 0; i < statsCount; i++) { MapleCharacterStat stat = (MapleCharacterStat)pr.ReadLong(); int addValue = pr.ReadInt(); if (addValue > 0) { statsAssign.Add(stat, addValue); } } SortedDictionary <MapleCharacterStat, long> statsUpdate = new SortedDictionary <MapleCharacterStat, long>(); foreach (KeyValuePair <MapleCharacterStat, long> kvp in statsAssign) { if (chr.AP < kvp.Value) { continue; } short statInc = (short)kvp.Value; switch (kvp.Key) { case MapleCharacterStat.Str: if (chr.Str + statInc <= 9999) { chr.Str += statInc; chr.AP -= statInc; statsUpdate.Add(MapleCharacterStat.Str, chr.Str); } break; case MapleCharacterStat.Dex: if (chr.Dex + statInc <= 9999) { chr.Dex += statInc; chr.AP -= statInc; statsUpdate.Add(MapleCharacterStat.Dex, chr.Dex); } break; case MapleCharacterStat.Int: if (chr.Int + statInc <= 9999) { chr.Int += statInc; chr.AP -= statInc; statsUpdate.Add(MapleCharacterStat.Int, chr.Int); } break; case MapleCharacterStat.Luk: if (chr.Luk + statInc <= 9999) { chr.Luk += statInc; chr.AP -= statInc; statsUpdate.Add(MapleCharacterStat.Luk, chr.Luk); } break; default: ServerConsole.Error("Unhandled stat in AutoAssignAp handling: " + kvp.Key); break; } } statsUpdate.Add(MapleCharacterStat.Ap, chr.AP); MapleCharacter.UpdateStats(c, statsUpdate, true); }
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(); } } }