/// <title>Saga.AddStep</title> /// <code> /// Saga.AddStep(cid, QuestID, StepId, State); /// </code> /// <description> /// Adds a step to the quest. This can only be done during initialisation. /// 0 = Hidden, 1 = Visible, 2 = Completed /// </description> /// <example> ///function QUEST_START(cid) /// -- Initialize all quest steps /// -- Initialize all starting navigation points /// /// Saga.AddStep(cid, QuestID, 101, 1); /// Saga.AddStep(cid, QuestID, 102, 0); /// Saga.AddStep(cid, QuestID, 103, 0); /// Saga.InsertQuest(cid, QuestID, 1); /// /// return 0; ///end /// </example> public static bool NpcGiveItem(uint CID, uint ItemId, byte ItemCount) { Character value; if (LifeCycle.TryGetById(CID, out value)) { Rag2Item item; if (Singleton.Item.TryGetItemWithCount(ItemId, ItemCount, out item)) { int index = value.container.Add(item); if (index > -1) { SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.SessionId = value.id; spkt.UpdateReason = (byte)ItemUpdateReason.ReceiveFromNpc; spkt.SetItem(item, index); value.client.Send((byte[])spkt); return(true); } } } return(false); }
/// <summary> /// Occurs when retrieving item attachement from the id. /// </summary> /// <param name="cpkt"></param> private void CM_RETRIEVEITEMATTACHMENT(CMSG_GETITEMATTACHMENT cpkt) { byte result = 0; try { Rag2Item item = Singleton.Database.GetItemAttachment(cpkt.MailId); //No attachment if (item == null) { result = 1; } //Not the same item type else if (item.info.item != cpkt.ItemId) { result = 1; } //Not enough space else if (this.character.container.Count == this.character.container.Capacity) { result = 1; } //Update the database else if (Singleton.Database.UpdateItemAttachment(cpkt.MailId, null) == false) { result = 1; } //Everything is okay else { int index = this.character.container.Add(item); SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.UpdateReason = (byte)ItemUpdateReason.AttachmentSent; spkt.SessionId = this.character.id; spkt.SetItem(item, index); this.Send((byte[])spkt); } } finally { SMSG_MAILITEMAWNSER spkt = new SMSG_MAILITEMAWNSER(); spkt.SessionId = cpkt.SessionId; spkt.Result = result; this.Send((byte[])spkt); } }
public static bool GiveItem(Character character, uint item, byte count) { Rag2Item iventoryitem; if (Singleton.Item.TryGetItemWithCount(item, count, out iventoryitem)) { int index = character.container.Add(iventoryitem); if (index > -1) { character.container[index] = iventoryitem; SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.UpdateReason = 0; spkt.SetItem(iventoryitem, index); spkt.SessionId = character.id; character.client.Send((byte[])spkt); QuestBase.UserObtainedItem(item, character); return(true); } } return(false); }
/// <summary> /// Occurs when your aggreeing with the trade. /// After the trade content has been agreed. /// </summary> private void CM_TRADECONFIRM(CMSG_TRADECONFIRM cpkt) { TradeSession session = this.character.TradeSession; if (session != null) { //OBTAIN THE ORGIN TARGET Character target; TradeSession.TradeItem[] Items; if (this.character.TradeSession.Source == this.character) { target = session.Target; Items = session.TargetItem; } else { target = session.Source; Items = session.SourceItem; } //Calculate required slots int slots = 0; for (int i = 0; i < 16; i++) { if (Items[i] == null) { continue; } slots++; } if (slots > this.character.container.Capacity - this.character.container.Count) { //Not enough space oponent SMSG_TRADERESULT2 spkt = new SMSG_TRADERESULT2(); spkt.Reason = (byte)TradeResult.TargetNotEnoughInventorySpace; spkt.SessionId = target.id; target.client.Send((byte[])spkt); //Not enough space myself SMSG_TRADERESULT2 spkt2 = new SMSG_TRADERESULT2(); spkt2.Reason = (byte)TradeResult.NotEnoughIventorySpace; spkt2.SessionId = this.character.id; this.Send((byte[])spkt2); //Set tradesession to null; this.character.TradeSession = null; target.TradeSession = null; return; } else { if (session.Source == this.character) { session.SourceHasAgreed = true; } else { session.TargetHasAgreed = true; } } if (session.TargetHasAgreed && session.SourceHasAgreed) { target.ZENY += session.ZenySource; this.character.ZENY -= session.ZenySource; target.ZENY -= session.ZenyTarget; this.character.ZENY += session.ZenyTarget; List <Rag2Item> SourceList = new List <Rag2Item>(); List <Rag2Item> TargetList = new List <Rag2Item>(); for (int i = 0; i < 16; i++) { TradeSession.TradeItem item = session.SourceItem[i]; if (item == null) { continue; } Rag2Item ragitem = this.character.container[item.Slot]; if (ragitem.count - item.Count == 0) { SourceList.Add(ragitem); this.character.container.RemoveAt(item.Slot); SMSG_DELETEITEM spkt = new SMSG_DELETEITEM(); spkt.Container = 2; spkt.Index = item.Slot; spkt.SessionId = this.character.id; spkt.UpdateReason = (byte)ItemUpdateReason.SendToTrader; this.Send((byte[])spkt); } else { SourceList.Add(ragitem.Clone(item.Count)); ragitem.count -= item.Count; SMSG_UPDATEITEM spkt = new SMSG_UPDATEITEM(); spkt.Container = 2; spkt.Index = item.Slot; spkt.SessionId = this.character.id; spkt.UpdateReason = (byte)ItemUpdateReason.SendToTrader; spkt.UpdateType = 4; this.Send((byte[])spkt); } } for (int i = 0; i < 16; i++) { TradeSession.TradeItem item = session.TargetItem[i]; if (item == null) { continue; } Rag2Item ragitem = target.container[item.Slot]; if (ragitem.count - item.Count == 0) { TargetList.Add(ragitem); this.character.container.RemoveAt(item.Slot); SMSG_DELETEITEM spkt = new SMSG_DELETEITEM(); spkt.Container = 2; spkt.Index = item.Slot; spkt.SessionId = target.id; spkt.UpdateReason = (byte)ItemUpdateReason.SendToTrader; target.client.Send((byte[])spkt); } else { TargetList.Add(ragitem.Clone(item.Count)); ragitem.count -= item.Count; SMSG_UPDATEITEM spkt = new SMSG_UPDATEITEM(); spkt.Container = 2; spkt.Index = item.Slot; spkt.SessionId = target.id; spkt.UpdateReason = (byte)ItemUpdateReason.SendToTrader; spkt.UpdateType = 4; target.client.Send((byte[])spkt); } } for (int i = 0; i < SourceList.Count; i++) { Rag2Item ragitem = SourceList[i]; int index = target.container.Add(ragitem); SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.UpdateReason = (byte)ItemUpdateReason.ReceiveFromTrade; spkt.SessionId = target.id; spkt.SetItem(ragitem, index); target.client.Send((byte[])spkt); } for (int i = 0; i < TargetList.Count; i++) { Rag2Item ragitem = TargetList[i]; int index = this.character.container.Add(ragitem); SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.UpdateReason = (byte)ItemUpdateReason.ReceiveFromTrade; spkt.SessionId = this.character.id; spkt.SetItem(ragitem, index); this.Send((byte[])spkt); } //Update zeny yourself SMSG_SENDZENY spkt4 = new SMSG_SENDZENY(); spkt4.SessionId = this.character.id; spkt4.Zeny = this.character.ZENY; this.Send((byte[])spkt4); //Update zeny opponent SMSG_SENDZENY spkt5 = new SMSG_SENDZENY(); spkt5.SessionId = target.id; spkt5.Zeny = target.ZENY; target.client.Send((byte[])spkt5); //Set traderesult to succesfull SMSG_TRADERESULT2 spkt3 = new SMSG_TRADERESULT2(); spkt3.SessionId = this.character.id; this.Send((byte[])spkt3); //Set traderesult successfull oponent SMSG_TRADERESULT2 spkt2 = new SMSG_TRADERESULT2(); spkt2.SessionId = target.id; target.client.Send((byte[])spkt2); //Set the tradesession to null this.character.TradeSession = null; target.TradeSession = null; } } }
/// <summary> /// Occurs when selecting a event reward /// </summary> /// <param name="cpkt"></param> private void CM_EVENTRECIEVEITEM(CMSG_RECEIVEEVENTITEM cpkt) { SMSG_EVENTINFO2 spkt = new SMSG_EVENTINFO2(); spkt.Result = 1; try { Rag2Item item; EventItem b = Singleton.Database.FindEventItemById(this.character, cpkt.RewardId); if (b.ItemId == 0) { //Event reward not found spkt.Result = 1; } else if (b.ItemCount == 0) { //Event reward not found spkt.Result = 1; } else if (this.character.container.Count == this.character.container.Capacity) { //Full storage spkt.Result = 1; } else if (!Singleton.Item.TryGetItemWithCount(b.ItemId, b.ItemCount, out item)) { //Item id not found spkt.Result = 1; } else { Singleton.Database.DeleteEventItemId(cpkt.RewardId); //AMOUNT USED IN DECREMENT CALCULATIONS int index = this.character.container.FindFirstFreeIndex(); if (index > -1) { this.character.container[index] = item; SMSG_ADDITEM spkt2 = new SMSG_ADDITEM(); spkt2.Container = 2; spkt2.UpdateReason = (byte)ItemUpdateReason.EventReceived; spkt2.SetItem(item, index); spkt2.SessionId = this.character.id; this.Send((byte[])spkt2); //Type is used to calc type of item //(21 seems to be used for Applogy Item) if (item.info.type == 21) { Common.Skills.UpdateAddition(this.character, item.info.option_id); } } spkt.Result = 0; } foreach (EventItem rewardItem in Singleton.Database.FindEventItemList(character)) { spkt.AddItem(rewardItem.EventId, rewardItem.ItemId, rewardItem.ItemCount); } } catch (Exception e) { Trace.TraceError(e.ToString()); } finally { spkt.SessionId = character.id; this.Send((byte[])spkt); } }
/// <summary> /// Occurs when a player selects a drop from the droplist. /// </summary> /// <param name="cpkt"></param> private void CM_DROPSELECT(CMSG_DROPSELECT cpkt) { try { MapObject target = null; Rag2Collection list = null; LootCollection loot = this.character.Tag as LootCollection; //Corpse disappeared already if (!Regiontree.TryFind(cpkt.ActorID, this.character, out target)) { SMSG_NPCDROPLISTRESULT spkt = new SMSG_NPCDROPLISTRESULT(); spkt.ActorID = cpkt.ActorID; spkt.Result = 0; spkt.SessionId = this.character.id; this.Send((byte[])spkt); return; } //Uknown looting error (not implamented itseems) else if (loot == null) { SMSG_NPCDROPLISTRESULT spkt = new SMSG_NPCDROPLISTRESULT(); spkt.ActorID = cpkt.ActorID; spkt.Result = 4; spkt.SessionId = this.character.id; this.Send((byte[])spkt); return; } else { list = loot.Lootlist; } //OBTAIN THE REQUIRED ITEMS FROM THE MERCHANT Rag2Item item = list[cpkt.Index]; if (item == null) { return; } //TEMP HELPER VARIABLES int nstacked = 0; List <int> update_queue = new List <int>(); //WALKTHROUGH EVERY ITEM AND CHECK IF IT CAN BE STACKED foreach (int index in this.character.container.FindAllItems(item.info.item)) { Rag2Item invItem = this.character.container[index]; nstacked += Math.Min(0, (item.info.max_stack - invItem.count)); if (invItem.count < item.info.max_stack) { update_queue.Add(index); } } //CALCULATE THE AMOUNT OF NEW SLOTS REQUIRED int req_hslot = (int)item.count % (int)this.character.container.Capacity; int req_slots = item.count; //int max_stack = (item.info.max_stack == 0) ? 1 : item.info.max_stack; if (item.info.max_stack > 0) { int div_rem = (int)((item.count - nstacked) / item.info.max_stack); int div_rem2 = (req_hslot > 0) ? 1 : 0; req_slots = div_rem + div_rem2; } if (this.character.container.Count + req_slots > this.character.container.Capacity) { SMSG_NPCDROPLISTRESULT spkt = new SMSG_NPCDROPLISTRESULT(); spkt.ActorID = cpkt.ActorID; spkt.Result = 3; spkt.SessionId = this.character.id; this.Send((byte[])spkt); return; } //AMOUNT USED IN DECREMENT CALCULATIONS int amount = (int)item.count; //ITERATE THROUGH ALL AVAILABLE ITEM THAT CAN BE PROCESSED FOR UPDATES foreach (int invIndex in update_queue) { Rag2Item invItem = this.character.container[invIndex]; int leftover = item.info.max_stack - invItem.count; leftover = Math.Max(0, Math.Min(amount, leftover)); invItem.count += leftover; amount -= leftover; SMSG_UPDATEITEM spkt = new SMSG_UPDATEITEM(); spkt.Index = (byte)invIndex; spkt.UpdateReason = (byte)ItemUpdateReason.Obtained; spkt.UpdateType = 4; spkt.Container = 2; spkt.Amount = (byte)invItem.count; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } //ITERATE THROUGH EVERY FREE INDEX AND PROCESS IT foreach (int invIndex in this.character.container.FindFreeIndexes()) { if (amount == 0) { break; } int leftover = Math.Min(amount, item.info.max_stack); Rag2Item invItem = item.Clone(leftover); this.character.container[invIndex] = invItem; amount -= leftover; SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.UpdateReason = (byte)ItemUpdateReason.Obtained; spkt.SetItem(invItem, invIndex); spkt.SessionId = this.character.id; this.Send((byte[])spkt); } //CHECK THE LIST if (amount == 0) { list.RemoveAt(cpkt.Index); } else { item.count = amount; } //REFRESH THE INVENTORY loot.Open(this.character, target); QuestBase.UserObtainedItem(item.info.item, this.character); if (this.character.sessionParty != null) { for (int i = 0; i < this.character.sessionParty._Characters.Count; i++) { Character partyTarget = this.character.sessionParty._Characters[i]; if (partyTarget.id == this.character.id) { continue; } SMSG_PARTYMEMBERLOOT spkt2 = new SMSG_PARTYMEMBERLOOT(); spkt2.SessionId = partyTarget.id; spkt2.Index = (byte)(i + 1); spkt2.ActorId = this.character.id; spkt2.ItemId = item.info.item; partyTarget.client.Send((byte[])spkt2); } } } //CATCH ALL UNKNOWN ERRORS catch (Exception e) { SMSG_NPCDROPLISTRESULT spkt = new SMSG_NPCDROPLISTRESULT(); spkt.ActorID = cpkt.ActorID; spkt.Result = 5; spkt.SessionId = this.character.id; this.Send((byte[])spkt); Console.WriteLine(e); } }
/// <summary> /// Occurs when exchanging goods /// </summary> /// <param name="cpkt"></param> private void CM_EXCHANGEGOODS(CMSG_SUPPLYEXCHANGE cpkt) { byte useresult = 1; byte result = 5; try { SingleTradelist stradelist = this.character.Tag as SingleTradelist; GroupedTradelist gtradelist = this.character.Tag as GroupedTradelist; List <Rag2Item> Production = null; List <Rag2Item> Supplyment = null; uint supplymoney = 0; uint productionmoney = 0; //Obtain type of tradelist if (stradelist != null) { useresult = 1; Production = stradelist.list.GetProductionlist; Supplyment = stradelist.list.GetSupplementlist; supplymoney = stradelist.supplementzeny; productionmoney = stradelist.productionzeny; } else if (gtradelist != null) { useresult = 2; Production = gtradelist.list[cpkt.ButtonId].GetProductionlist; Supplyment = gtradelist.list[cpkt.ButtonId].GetSupplementlist; } else { return; } uint reqzeny = productionmoney - supplymoney; if (reqzeny < 0 && this.character.ZENY - reqzeny <= 0) { result = 3; return; } List <byte> ListOfIndexes = new List <byte>(); int numdelitems = 0; for (int i = 0; i < Supplyment.Count; i++) { bool IsFound = false; Rag2Item item2 = Supplyment[i]; foreach (KeyValuePair <byte, Rag2Item> pair in this.character.container.GetAllItems()) { Rag2Item item1 = pair.Value; bool IsSame = item1.clvl == item2.clvl && item1.info == item2.info && item1.dyecolor == item2.dyecolor && item1.count >= item2.count && item1.clvl == item2.clvl; //Set the to true, keep true if already true; if (IsSame == true) { ListOfIndexes.Add(pair.Key); IsFound |= IsSame; int count = item1.count - item2.count; if (count == 0) { numdelitems++; } break; } } if (IsFound == false) { break; } } if (ListOfIndexes.Count != Supplyment.Count) { result = 4; return; } int reqslots = Production.Count - numdelitems; if (reqslots > 0 && this.character.container.Count + reqslots > this.character.container.Capacity) { result = 2; return; } for (int i = 0; i < ListOfIndexes.Count; i++) { int index = ListOfIndexes[i]; int newcount = this.character.container[index].count - Supplyment[i].count; if (newcount == 0) { this.character.container.RemoveAt(index); SMSG_DELETEITEM spkt = new SMSG_DELETEITEM(); spkt.Index = (byte)index; spkt.Container = 2; spkt.UpdateReason = (byte)ItemUpdateReason.SendToTrader; spkt.SessionId = this.character.id; this.Send((byte[])spkt); } else { this.character.container[index].count = newcount; SMSG_UPDATEITEM spkt = new SMSG_UPDATEITEM(); spkt.Amount = (byte)newcount; spkt.UpdateReason = (byte)ItemUpdateReason.SendToTrader; spkt.UpdateType = 4; spkt.Container = 2; spkt.SessionId = this.character.id; spkt.Index = (byte)index; this.Send((byte[])spkt); } } foreach (Rag2Item item in Production) { int index = this.character.container.Add(item); SMSG_ADDITEM spkt = new SMSG_ADDITEM(); spkt.Container = 2; spkt.UpdateReason = (byte)ItemUpdateReason.ReceiveFromTrade; spkt.SetItem(item, index); spkt.SessionId = this.character.id; this.Send((byte[])spkt); } result = 0; } finally { SMSG_SUPPLYLISTRESULT spkt = new SMSG_SUPPLYLISTRESULT(); if (useresult == 2) { spkt.Reason1 = 1; spkt.Reason2 = result; } else if (useresult == 1) { spkt.Reason2 = result; } spkt.SessionId = this.character.id; this.Send((byte[])spkt); } }