/// <summary> /// The parse action set. /// </summary> /// <param name="actions"> /// The actions. /// </param> /// <exception cref="Exception"> /// </exception> private void ParseActionSet(List <AOAction> actions) { bool flag = this.br.ReadInt32() != 36; if (flag) { throw new Exception("Why am I here?"); } int arg_3D_0 = 1; int num = this.br.Read3F1(); int num2 = arg_3D_0; checked { while (true) { int arg_160_0 = num2; int num3 = num; if (arg_160_0 > num3) { break; } int actionNum = this.br.ReadInt32(); AOAction aoa = new AOAction(); aoa.ActionType = (ActionType)Enum.ToObject(typeof(ActionType), actionNum); int numreqs = this.br.Read3F1(); List <Requirement> cookedreqs = this.ReadReqs(numreqs); foreach (Requirement REQ in cookedreqs) { aoa.Requirements.Add(REQ); } if (actions == null) { actions = new List <AOAction>(); } actions.Add(aoa); cookedreqs.Clear(); num2++; } } }
/// <summary> /// </summary> /// <param name="page"> /// </param> /// <param name="item"> /// </param> /// <returns> /// </returns> private AOAction getAction(IInventoryPage page, IItem item) { AOAction action = null; // TODO: Add special check for social page if ((page is ArmorInventoryPage) || (page is ImplantInventoryPage)) { action = item.ItemActions.SingleOrDefault(x => x.ActionType == ActionType.ToWear); if (action == null) { return(new AOAction()); } } if (page is WeaponInventoryPage) { action = item.ItemActions.SingleOrDefault(x => x.ActionType == ActionType.ToWield); if (action == null) { return(new AOAction()); } } if (page is PlayerInventoryPage) { // No checks needed for unequipping return(new AOAction()); } if (page is SocialArmorInventoryPage) { // TODO: Check for side, sex, breed conditionals return(new AOAction()); } if (action == null) { throw new NotSupportedException( "No suitable action found for equipping to this page: " + page.GetType()); } return(action); }
/// <summary> /// </summary> public void CreateInterpolatedRequirements() { if (this.templateLow.Quality == this.templateHigh.Quality) { this.actions = this.templateLow.Actions; this.events = this.templateLow.Events; return; } float factor = (this.Quality - this.templateLow.Quality) / (this.templateHigh.Quality - this.templateLow.Quality); if (this.actions == null) { if (this.Quality == this.templateLow.Quality) { this.actions = this.templateLow.Actions; } else if (this.Quality == this.templateHigh.Quality) { this.actions = this.templateHigh.Actions; } else { // We need to create the interpolated actions first this.actions = new List <AOAction>(); foreach (AOAction action in this.templateLow.Actions) { AOAction temp = this.templateLow.Actions.Single(x => x.ActionType == action.ActionType).Copy(); AOAction highActions = this.templateHigh.Actions.Single(x => x.ActionType == action.ActionType); AOAction lowActions = action; for (int reqnum = 0; reqnum < highActions.Requirements.Count; reqnum++) { temp.Requirements[reqnum].Value = Convert.ToInt32( factor * (highActions.Requirements[reqnum].Value - lowActions.Requirements[reqnum].Value)); } this.actions.Add(temp); } } } if (this.events == null) { // We need to create interpolated events first if (this.Quality == this.templateLow.Quality) { this.events = this.templateLow.Events; } else if (this.Quality == this.templateHigh.Quality) { this.events = this.templateHigh.Events; } else { this.events = new List <Event>(); for (int evnum = 0; evnum < this.templateLow.Events.Count; evnum++) { Event temp = this.templateLow.Events[evnum].Copy(); for (int funcnum = 0; funcnum < this.templateLow.Events[evnum].Functions.Count; funcnum++) { for (int reqnum = 0; reqnum < this.templateLow.Events[evnum].Functions[funcnum].Requirements.Count; reqnum++) { temp.Functions[funcnum].Requirements[reqnum].Value = Convert.ToInt32( factor * (this.templateHigh.Events[evnum].Functions[funcnum].Requirements[reqnum].Value - this.templateLow.Events[evnum].Functions[funcnum].Requirements[reqnum] .Value) + this.templateLow.Events[evnum].Functions[funcnum].Requirements[reqnum].Value); } for (int argnum = 0; argnum < this.templateLow.Events[evnum].Functions[funcnum].Arguments.Values.Count; argnum++) { if (temp.Functions[funcnum].Arguments.Values[argnum].IsTypeOf <int>() == true) { temp.Functions[funcnum].Arguments.Values[argnum] = Convert.ToInt32( factor * (this.templateHigh.Events[evnum].Functions[funcnum].Arguments.Values[ argnum].AsInt32() - this.templateLow.Events[evnum].Functions[funcnum].Arguments.Values[ argnum].AsInt32()) + this.templateLow.Events[evnum].Functions[funcnum].Arguments.Values[argnum] .AsInt32()); } else if (temp.Functions[funcnum].Arguments.Values[argnum].IsTypeOf <float>() == true) { temp.Functions[funcnum].Arguments.Values[argnum] = factor * (this.templateHigh.Events[evnum ].Functions[funcnum] .Arguments.Values[argnum] .AsSingle() - this.templateLow.Events[ evnum].Functions[funcnum] .Arguments.Values[argnum] .AsSingle()) + this.templateLow.Events[evnum] .Functions[funcnum].Arguments .Values[argnum].AsSingle(); } } } this.events.Add(temp); } } } }
/// <summary> /// </summary> /// <param name="message"> /// </param> /// <param name="client"> /// </param> protected override void Read(ContainerAddItemMessage message, IZoneClient client) { bool noAppearanceUpdate = false; /* Container ID's: * 0065 Weaponpage * 0066 Armorpage * 0067 Implantpage * 0068 Inventory (places 64-93) * 0069 Bank * 006B Backpack * 006C KnuBot Trade Window * 006E Overflow window * 006F Trade Window * 0073 Socialpage * 0767 Shop Inventory * 0790 Playershop Inventory * DEAD Trade Window (incoming) It's bank now (when you put something into the bank) */ IInventoryPage sendingPage = Pool.Instance.GetObject <IInventoryPage>( message.Identity, new Identity() { Type = (IdentityType)message.Identity.Instance, Instance = (int)message.SourceContainer.Type }); int fromPlacement = message.SourceContainer.Instance; Identity toIdentity = message.Target; int toPlacement = message.TargetPlacement; // Where and what does need to be moved/added? IItem itemFrom = sendingPage[fromPlacement]; // Receiver of the item (IInstancedEntity, can be mostly all from NPC, Character or Bag, later even playfields) // Turn 0xDEAD into C350 if instance is the same if (toIdentity.Type == IdentityType.IncomingTradeWindow) { toIdentity.Type = IdentityType.CanbeAffected; } IItemContainer itemReceiver = client.Controller.Character.Playfield.FindByIdentity(toIdentity) as IItemContainer; if (itemReceiver == null) { throw new ArgumentOutOfRangeException( "No Entity found: " + message.Target.Type.ToString() + ":" + message.Target.Instance); } // On which inventorypage should the item be added? IInventoryPage receivingPage; if ((toPlacement == 0x6f) && (message.Target.Type == IdentityType.IncomingTradeWindow)) { receivingPage = itemReceiver.BaseInventory.Pages[(int)IdentityType.Bank]; } else { receivingPage = itemReceiver.BaseInventory.PageFromSlot(toPlacement); } // Get standard page if toplacement cant be found (0x6F for next free slot) // TODO: If Entities are not the same (other player, bag etc) then always add to the standard page if ((receivingPage == null) || (itemReceiver.GetType() != client.Controller.Character.GetType())) { receivingPage = itemReceiver.BaseInventory.Pages[itemReceiver.BaseInventory.StandardPage]; } if (receivingPage == null) { throw new ArgumentOutOfRangeException("No inventorypage found."); } if (toPlacement == 0x6f) { toPlacement = receivingPage.FindFreeSlot(); } // Is there already a item? IItem itemTo; try { itemTo = receivingPage[toPlacement]; } catch (Exception) { itemTo = null; } // Calculating delay for equip/unequip/switch gear int delay = 20; client.Controller.Character.DoNotDoTimers = true; IItemSlotHandler equipTo = receivingPage as IItemSlotHandler; IItemSlotHandler unequipFrom = sendingPage as IItemSlotHandler; noAppearanceUpdate = !((equipTo is WeaponInventoryPage) || (equipTo is ArmorInventoryPage) || (equipTo is SocialArmorInventoryPage)); noAppearanceUpdate &= !((unequipFrom is WeaponInventoryPage) || (unequipFrom is ArmorInventoryPage) || (unequipFrom is SocialArmorInventoryPage)); if (equipTo != null) { if (itemTo != null) { if (receivingPage.NeedsItemCheck) { AOAction action = this.getAction(sendingPage, itemFrom); if (action.CheckRequirements(client.Controller.Character)) { UnEquip.Send(client, receivingPage, toPlacement); if (!noAppearanceUpdate) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such delay = (itemFrom.GetAttribute(211) == 1234567890 ? 20 : itemFrom.GetAttribute(211)) + (itemTo.GetAttribute(211) == 1234567890 ? 20 : itemTo.GetAttribute(211)); } Thread.Sleep(delay * 10); // social has to wait for 0.2 secs too (for helmet update) client.Controller.Character.Send(message); equipTo.HotSwap(sendingPage, fromPlacement, toPlacement); Equip.Send(client, receivingPage, toPlacement); } } } else { if (receivingPage.NeedsItemCheck) { if (itemFrom == null) { throw new NullReferenceException("itemFrom can not be null, possible inventory error"); } AOAction action = this.getAction(receivingPage, itemFrom); if (action.CheckRequirements(client.Controller.Character)) { if (!noAppearanceUpdate) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such delay = itemFrom.GetAttribute(211); if ((equipTo is SocialArmorInventoryPage) || (delay == 1234567890)) { delay = 20; } Thread.Sleep(delay * 10); } if (sendingPage == receivingPage) { // Switch rings for example UnEquip.Send(client, sendingPage, fromPlacement); } client.Controller.Character.Send(message); equipTo.Equip(sendingPage, fromPlacement, toPlacement); Equip.Send(client, receivingPage, toPlacement); } } } } else { if (unequipFrom != null) { // Send to client first if (!noAppearanceUpdate) { // Equipmentpages need delays // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such delay = itemFrom.GetAttribute(211); if ((unequipFrom is SocialArmorInventoryPage) || (delay == 1234567890)) { delay = 20; } Thread.Sleep(delay * 10); } UnEquip.Send(client, sendingPage, fromPlacement); unequipFrom.Unequip(fromPlacement, receivingPage, toPlacement); client.Controller.Character.Send(message); } else { // No equipment page involved, just send ContainerAddItemMessage back message.TargetPlacement = receivingPage.FindFreeSlot(); IItem item = sendingPage.Remove(fromPlacement); receivingPage.Add(message.TargetPlacement, item); client.Controller.Character.Send(message); } } client.Controller.Character.DoNotDoTimers = false; // Apply item functions before sending the appearanceupdate message client.Controller.Character.CalculateSkills(); /* * if (!noAppearanceUpdate) * { * AppearanceUpdateMessageHandler.Default.Send(client.Controller.Character); * } */ }