public static void ItemUpdate(Client client, MabiCreature creature, MabiItem item) { var packet = new MabiPacket(Op.ItemUpdate, creature.Id); packet.AddItemInfo(item, ItemPacketType.Private); client.Send(packet); }
/// <summary> /// Sends ItemAmount to creature's client. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> public static void ItemAmount(MabiCreature creature, MabiItem item) { var packet = new MabiPacket(Op.ItemAmount, creature.Id); packet.PutLong(item.Id); packet.PutShort(item.Info.Amount); packet.PutByte(2); // ? (related to the 2 in move item?) creature.Client.Send(packet); }
public void AddItem(string tab, uint itemClass, uint color1, uint color2, uint color3, ushort amount = 1, int price = -1) { var item = new MabiItem(itemClass); item.Info.Amount = Math.Min(amount, item.StackMax); item.Info.ColorA = color1; item.Info.ColorB = color2; item.Info.ColorC = color3; this.AddItem(tab, item, amount, price); }
/// <summary> /// Adds 1 prof to the given item and sends an update to the /// creature's client, if needed. /// </summary> /// <param name="creature"></param> /// <param name="item"></param> public static void GiveItemExp(MabiCreature creature, MabiItem item) { //if (item != null && item.OptionInfo.Experience < 10000) //{ // item.OptionInfo.Experience += WorldConf.ItemExp; // if (item.OptionInfo.Experience > 1000) // item.OptionInfo.Experience = 1000; // creature.Client.Send(PacketCreator.ItemProfUpdate(creature, item)); //} }
/// <summary> /// Decrements item amount by one and sends update packets. /// </summary> /// <param name="item"></param> public void DecItem(MabiItem item) { if (!this.Items.Contains(item)) return; item.Info.Amount--; if (item.StackType != BundleType.Sac && item.Info.Amount < 1) this.Items.Remove(item); this.ItemUpdate(item); EventManager.CreatureEvents.OnCreatureItemAction(this, item.Info.Class); }
protected virtual void EquipItem(Pocket pocket, uint itemClass, uint color1 = 0, uint color2 = 0, uint color3 = 0) { var item = new MabiItem(itemClass); item.Info.ColorA = color1; item.Info.ColorB = color2; item.Info.ColorC = color3; item.Info.Pocket = (byte)pocket; //var inPocket = this.Creature.GetItemInPocket(slot); //if (inPocket != null) // this.Creature.Items.Remove(inPocket); this.Creature.Items.Add(item); Send.EquipmentChanged(this.Creature, item); }
protected virtual void EquipItem(Pocket pocket, uint itemClass, uint color1 = 0, uint color2 = 0, uint color3 = 0) { if (!pocket.IsEquip()) return; var item = new MabiItem(itemClass); item.Info.ColorA = color1; item.Info.ColorB = color2; item.Info.ColorC = color3; //var inPocket = this.Creature.GetItemInPocket(slot); //if (inPocket != null) // this.Creature.Items.Remove(inPocket); this.Creature.Inventory.ForceAdd(item, pocket); Send.EquipmentChanged(this.Creature, item); }
protected MabiPropFunc PropDrop(uint dropType) { return (client, creature, prop) => { if (Rnd() > WorldConf.PropDropRate) return; var di = MabiData.PropDropDb.Find(dropType); if (di == null) { Logger.Warning("Unknown prop drop type '{0}'.", dropType); return; } var dii = di.GetRndItem(RandomProvider.Get()); var item = new MabiItem(dii.ItemClass); item.Info.Amount = dii.Amount > 1 ? (ushort)this.Rnd(1, dii.Amount) : (ushort)1; WorldManager.Instance.DropItem(item, prop.Region, (uint)prop.Info.X, (uint)prop.Info.Y); }; }
private void UpdateInventory(MabiItem item, Pocket source, Pocket target) { this.CheckLeftHand(item, source, target); this.UpdateEquipReferences(source, target); this.CheckEquipMoved(item, source, target); }
/// <summary> /// Unequips item in left hand/magazine, if item in right hand is moved. /// </summary> /// <param name="item"></param> /// <param name="source"></param> /// <param name="target"></param> private void CheckLeftHand(MabiItem item, Pocket source, Pocket target) { var pocketOfInterest = Pocket.None; if (source == Pocket.RightHand1 || source == Pocket.RightHand2) pocketOfInterest = source; if (target == Pocket.RightHand1 || target == Pocket.RightHand2) pocketOfInterest = target; if (pocketOfInterest != Pocket.None) { var leftPocket = pocketOfInterest + 2; // Left Hand 1/2 var leftItem = _pockets[leftPocket].GetItemAt(0, 0); if (leftItem == null) { leftPocket += 2; // Magazine 1/2 leftItem = _pockets[leftPocket].GetItemAt(0, 0); } if (leftItem != null) { // Try inventory first. // TODO: List of pockets stuff can be auto-moved to. var success = _pockets[Pocket.Inventory].Add(leftItem); // Fallback, temp inv if (!success) success = _pockets[Pocket.Temporary].Add(leftItem); if (success) { _pockets[leftPocket].Remove(leftItem); Send.ItemMoveInfo(_creature, leftItem, leftPocket, null); Send.EquipmentMoved(_creature, leftPocket); } } } }
/// <summary> /// Sends EquipmentMoved and EquipmentChanged, if necessary. /// </summary> /// <param name="item"></param> /// <param name="source"></param> /// <param name="target"></param> private void CheckEquipMoved(MabiItem item, Pocket source, Pocket target) { if (source.IsEquip()) Send.EquipmentMoved(_creature, source); if (target.IsEquip()) { Send.EquipmentChanged(_creature, item); // TODO: Equip/Unequip item scripts switch (item.Info.Class) { // Umbrella Skill case 41021: case 41022: case 41023: case 41025: case 41026: case 41027: case 41061: case 41062: case 41063: if (!_creature.Skills.Has(SkillConst.Umbrella)) _creature.Skills.Give(SkillConst.Umbrella, SkillRank.Novice); break; // Spread Wings case 19138: case 19139: case 19140: case 19141: case 19142: case 19143: case 19157: case 19158: case 19159: if (!_creature.Skills.Has(SkillConst.SpreadWings)) _creature.Skills.Give(SkillConst.SpreadWings, SkillRank.Novice); break; } } }
/// <summary> /// Removes item from pocket. /// </summary> /// <param name="item"></param> public abstract bool Remove(MabiItem item);
private static void AddItemInfo(this MabiPacket packet, MabiItem item, ItemPacketType type) { packet.PutLong(item.Id); packet.PutByte((byte)type); packet.PutBin(item.Info); if (type == ItemPacketType.Public) { packet.PutByte(1); packet.PutByte(0); //packet.PutByte(0); // Bitmask // if & 1 // float packet.PutByte(1); packet.PutFloat(1); // Size multiplicator *hint: Server side giant key mod* packet.PutByte(item.FirstTimeAppear); // 0: No bouncing, 1: Bouncing, 2: Delayed bouncing } else if (type == ItemPacketType.Private) { packet.PutBin(item.OptionInfo); packet.PutString(item.Tags.ToString()); packet.PutString(""); packet.PutByte(0); // upgrade count? // for upgrades // Bin : 01 00 00 00 68 21 11 00 00 00 00 00 05 00 1E 00 00 00 00 00 0A 00 00 00 D3 E4 90 65 0A 00 00 00 F0 18 9E 65 packet.PutLong(item.QuestId); } }
public static float GetKnockDown(MabiItem weapon) { var count = weapon != null ? weapon.Info.KnockCount + 1 : 3; var speed = weapon != null ? weapon.AttackSpeed : AttackSpeed.Normal; switch (count) { default: case 1: return 100; case 2: switch (speed) { default: case AttackSpeed.VerySlow: return 70; case AttackSpeed.Slow: return 68; case AttackSpeed.Normal: return 68; // ? case AttackSpeed.Fast: return 68; // ? } case 3: switch (speed) { default: case AttackSpeed.VerySlow: return 60; case AttackSpeed.Slow: return 56; // ? case AttackSpeed.Normal: return 53; case AttackSpeed.Fast: return 50; } case 5: switch (speed) { default: case AttackSpeed.Fast: return 40; // ? case AttackSpeed.VeryFast: return 35; // ? } } }
public void AddItem(string tab, MabiItem item, ushort amount = 1, int price = -1) { if (price >= 0) { item.OptionInfo.Price = (uint)price * item.StackMax; item.OptionInfo.SellingPrice = (uint)(item.OptionInfo.Price * 0.1f); if (item.OptionInfo.Price < item.OptionInfo.SellingPrice) Logger.Warning(string.Format("Price for '{0}' is lower than the selling price. ({1} < {2})", item.Info.Class.ToString(), item.OptionInfo.Price, item.OptionInfo.SellingPrice)); } this.AddItems(tab, item); }
/// <summary> /// Adds item to pocket, without boundary and space checks. /// Only use when initializing! /// </summary> /// <param name="item"></param> /// <param name="pocket"></param> public void ForceAdd(MabiItem item, Pocket pocket) { _pockets[pocket].ForceAdd(item); this.UpdateEquipReferences(pocket); }
/// <summary> /// Decrements the item by amount, if it exists in this inventory. /// Sends ItemAmount/ItemRemove, depending on the resulting amount. /// </summary> /// <param name="item"></param> /// <param name="amount"></param> /// <returns></returns> public bool Decrement(MabiItem item, ushort amount = 1) { if (!this.Has(item) || item.Info.Amount == 0 || item.Info.Amount < amount) return false; item.Info.Amount -= amount; if (item.Info.Amount > 0 || item.StackType == BundleType.Sac) { Send.ItemAmount(_creature, item); } else { this.Remove(item); Send.ItemRemove(_creature, item); } return true; }
/// <summary> /// Puts new item(s) of class 'id' into the inventory. /// If item is stackable it is "fit in", filling stacks first. /// A sack is set to the amount and added as one item. /// If it's not a sac/stackable you'll get multiple new items. /// Uses temp inv if necessary. /// </summary> /// <param name="itemId"></param> /// <param name="amount"></param> /// <returns></returns> public bool Add(uint itemId, uint amount = 1) { var newItem = new MabiItem(itemId); if (newItem.StackType == BundleType.Stackable) { newItem.Info.Amount = (ushort)Math.Min(amount, ushort.MaxValue); return this.Insert(newItem, true, true); } else if (newItem.StackType == BundleType.Sac) { newItem.Info.Amount = (ushort)Math.Min(amount, ushort.MaxValue); return this.Add(newItem, true); } else { for (int i = 0; i < amount; ++i) this.Add(new MabiItem(itemId), true); return true; } }
/// <summary> /// Attempts to store item somewhere in the inventory. /// If temp is true, it will fallback to the temp inv, if there's not space. /// Returns whether the item was successfully stored somewhere. /// Sends ItemNew on success. /// </summary> /// <param name="item"></param> /// <param name="temp"></param> /// <returns></returns> public bool Add(MabiItem item, bool tempFallback, bool sendItemNew = true) { bool success; // Try inv success = _pockets[Pocket.Inventory].Add(item); // Try temp if (!success && tempFallback) success = _pockets[Pocket.Temporary].Add(item); // Inform about new item if (success && sendItemNew) Send.ItemInfo(_creature.Client, _creature, item); return success; }
/// <summary> /// Tries to put item into pocket, sends ItemNew on success. /// </summary> /// <param name="item"></param> /// <param name="pocket"></param> /// <returns></returns> public bool Add(MabiItem item, Pocket pocket) { var success = _pockets[pocket].Add(item); if (success) { Send.ItemInfo(_creature.Client, _creature, item); this.UpdateEquipReferences(pocket); } return success; }
/// <summary> /// Attempts to put item at the coordinates. If another item is /// in the new item's space it's returned in colliding. /// Returns whether the attempt was successful. /// </summary> /// <param name="item"></param> /// <param name="targetX"></param> /// <param name="targetY"></param> /// <param name="colliding"></param> /// <returns></returns> public abstract bool TryAdd(MabiItem item, byte targetX, byte targetY, out MabiItem colliding);
public static MabiPacket ItemRemove(MabiCreature creature, MabiItem item) { var p = new MabiPacket(Op.ItemRemove, creature.Id); p.PutLong(item.Id); p.PutByte(item.Info.Pocket); return p; }
public static MabiPacket ItemAmount(MabiCreature creature, MabiItem item) { var p = new MabiPacket(Op.ItemAmount, creature.Id); p.PutLong(item.Id); p.PutShort(item.Info.Amount); p.PutByte(2); return p; }
public bool Move(MabiItem item, Pocket target, byte targetX, byte targetY) { if (!this.Has(target)) return false; var source = item.Pocket; var amount = item.Info.Amount; MabiItem collidingItem = null; if (!_pockets[target].TryAdd(item, targetX, targetY, out collidingItem)) return false; // If amount differs (item was added to stack) if (collidingItem != null && item.Info.Amount != amount) { Send.ItemAmount(_creature, collidingItem); // Left overs, update if (item.Info.Amount > 0) { Send.ItemAmount(_creature, item); } // All in, remove from cursor. else { _pockets[item.Pocket].Remove(item); Send.ItemRemove(_creature, item); } } else { // Remove the item from the source pocket _pockets[source].Remove(item); // Toss it in, it should be the cursor. if (collidingItem != null) _pockets[source].ForceAdd(collidingItem); Send.ItemMoveInfo(_creature, item, source, collidingItem); } this.UpdateInventory(item, source, target); return true; }
public void GiveItem(WorldClient client, uint id, ushort amount, uint color1, uint color2, uint color3) { var item = new MabiItem(id); item.Info.Amount = amount; item.Info.ColorA = color1; item.Info.ColorB = color2; item.Info.ColorC = color3; client.Character.Inventory.Add(item, true); }
/// <summary> /// Removes item from inventory. Sends ItemRemove on success, /// and possibly others, if equipment is removed. /// </summary> /// <param name="item"></param> /// <returns></returns> public bool Remove(MabiItem item) { foreach (var pocket in _pockets.Values) { if (pocket.Remove(item)) { this.UpdateInventory(item, item.Pocket, Pocket.None); Send.ItemRemove(_creature, item); return true; } } return false; }
/// <summary> /// Returns whether the item exists in this inventory. /// </summary> /// <param name="item"></param> /// <returns></returns> public bool Has(MabiItem item) { foreach (var pocket in _pockets.Values) if (pocket.Has(item)) return true; return false; }
/// <summary> /// Returns whether the item exists in this pocket. /// </summary> /// <param name="item"></param> /// <returns></returns> public abstract bool Has(MabiItem item);
private CommandResult Command_item(WorldClient client, MabiCreature creature, string[] args, string msg) { if (args.Length < 2 || args.Length == 4 || args.Length > 5) return CommandResult.WrongParameter; uint itemId = 0; if (!uint.TryParse(args[1], out itemId)) { // Couldn't parse uint, must be a spawn by name var itemName = args[1].Replace('_', ' '); // Search exact name first var newItemInfo = MabiData.ItemDb.Find(itemName); if (newItemInfo == null) { // Not found? Look for the next best thing. var itemInfo = MabiData.ItemDb.FindAll(itemName); if (itemInfo.Count < 1) { Send.ServerMessage(client, creature, Localization.Get("gm.item_nores"), itemName); // Item '{0}' not found in database. return CommandResult.Fail; } // Find best match int score = 10000; foreach (var ii in itemInfo) { int iScore = ii.Name.LevenshteinDistance(itemName); if (iScore < score) { score = iScore; newItemInfo = ii; } } Send.ServerMessage(client, creature, Localization.Get("gm.item_mures"), itemName, newItemInfo.Name); // Item '{0}' not found, using next best result, '{1}'. } itemId = newItemInfo.Id; } var info = MabiData.ItemDb.Find(itemId); if (info == null) { Send.ServerMessage(client, creature, Localization.Get("gm.item_nores"), itemId); // Item '{0}' not found in database. return CommandResult.Fail; } var newItem = new MabiItem(itemId); newItem.Info.Amount = 1; if (args.Length == 3) { // command id amount if (!ushort.TryParse(args[2], out newItem.Info.Amount)) { Send.ServerMessage(client, creature, Localization.Get("gm.item_amount")); // Invalid amount. return CommandResult.Fail; } // Just in case if (newItem.Info.Amount > newItem.StackMax) newItem.Info.Amount = newItem.StackMax; if (newItem.StackType == BundleType.None) newItem.Info.Amount = 1; } else if (args.Length == 5) { // command id color1-3 uint[] color = { 0, 0, 0 }; for (int i = 0; i < 3; ++i) { if (args[i + 2].StartsWith("0x")) { // Color in hex if (!uint.TryParse(args[i + 2].Replace("0x", ""), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out color[i])) { Send.ServerMessage(client, creature, Localization.Get("gm.item_hex"), args[i + 2]); // Invalid hex color '{0}'. return CommandResult.Fail; } } else if (uint.TryParse(args[i + 2], out color[i])) { // Mabi color color[i] += 0x10000000; } else { // Color by name switch (args[i + 2]) { case "black": color[i] = 0xFF000000; break; case "white": color[i] = 0xFFFFFFFF; break; default: Send.ServerMessage(client, creature, Localization.Get("gm.item_color"), args[i + 2]); // Unknown color '{0}'. return CommandResult.Fail; } } } newItem.Info.ColorA = color[0]; newItem.Info.ColorB = color[1]; newItem.Info.ColorC = color[2]; } if (args[0] == "drop") { // >drop var pos = client.Character.GetPosition(); WorldManager.Instance.DropItem(newItem, client.Character.Region, (uint)pos.X, (uint)pos.Y); } else { // >item //newItem.Info.Pocket = (byte)Pocket.Temporary; //creature.Items.Add(newItem); creature.Inventory.Add(newItem, Pocket.Temporary); //Send.ItemInfo(client, creature, newItem); } return CommandResult.Okay; }
/// <summary> /// Puts item into inventory, if possible. Tries to fill stacks first. /// If tempFallback is true, leftovers will be put into temp. /// Sends ItemAmount and ItemNew if required/enabled. /// </summary> /// <param name="item"></param> /// <param name="tempFallback"></param> /// <returns></returns> public bool Insert(MabiItem item, bool tempFallback, bool sendItemNew) { if (item.StackType == BundleType.Stackable) { // Try stacks/sacs first List<MabiItem> changed; _pockets[Pocket.Inventory].FillStacks(item, out changed); this.UpdateChangedItems(changed); // Add new item stacks as long as needed. while (item.Info.Amount > item.StackMax) { var newStackItem = new MabiItem(item); newStackItem.Info.Amount = item.StackMax; // Break if no new items can be added (no space left) if (!_pockets[Pocket.Inventory].Add(newStackItem)) break; Send.ItemInfo(_creature.Client, _creature, newStackItem); item.Info.Amount -= item.StackMax; } if (item.Info.Amount == 0) return true; } return this.Add(item, tempFallback, sendItemNew); }