public static void SetProperty(this Biota biota, PropertyInstanceId property, uint value, ReaderWriterLockSlim rwLock) { rwLock.EnterUpgradeableReadLock(); try { var result = biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property); if (result != null) { result.Value = value; } else { rwLock.EnterWriteLock(); try { var entity = new BiotaPropertiesIID { ObjectId = biota.Id, Type = (ushort)property, Value = value, Object = biota }; biota.BiotaPropertiesIID.Add(entity); } finally { rwLock.ExitWriteLock(); } } } finally { rwLock.ExitUpgradeableReadLock(); } }
public GameMessagePrivateUpdateInstanceID(WorldObject worldObject, PropertyInstanceId property, uint value) : base(GameMessageOpcode.PrivateUpdatePropertyInstanceID, GameMessageGroup.UIQueue) { Writer.Write(worldObject.Sequences.GetNextSequence(Sequence.SequenceType.UpdatePropertyInstanceID, property)); Writer.Write((uint)property); Writer.Write(value); }
public static bool TryRemoveProperty(this Biota biota, PropertyInstanceId property, out BiotaPropertiesIID entity, ReaderWriterLockSlim rwLock) { rwLock.EnterUpgradeableReadLock(); try { entity = biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property); if (entity != null) { rwLock.EnterWriteLock(); try { biota.BiotaPropertiesIID.Remove(entity); entity.Object = null; return(true); } finally { rwLock.ExitWriteLock(); } } return(false); } finally { rwLock.ExitUpgradeableReadLock(); } }
public void RemoveProperty(PropertyInstanceId property) { if (Biota.TryRemoveProperty(property, BiotaDatabaseLock, biotaPropertyInstanceIds)) { ChangesDetected = true; } }
public void SetProperty(PropertyInstanceId property, uint value) { Biota.SetProperty(property, value, BiotaDatabaseLock, biotaPropertyInstanceIds, out var biotaChanged); if (biotaChanged) { ChangesDetected = true; } }
public GameMessagePublicUpdateInstanceID(WorldObject worldObject, PropertyInstanceId iidPropertyId, ObjectGuid instanceGuid) : base(GameMessageOpcode.PublicUpdateInstanceId, GameMessageGroup.UIQueue) { Writer.Write(worldObject.Sequences.GetNextSequence(SequenceType.PublicUpdatePropertyInstanceId)); // wts Writer.WriteGuid(worldObject.Guid); // sender Writer.Write((uint)iidPropertyId); Writer.WriteGuid(instanceGuid); // new value of the container id }
public GameMessagePublicUpdateInstanceID(WorldObject worldObject, PropertyInstanceId property, ObjectGuid instanceGuid) : base(GameMessageOpcode.PublicUpdateInstanceId, GameMessageGroup.UIQueue) { Writer.Write(worldObject.Sequences.GetNextSequence(SequenceType.UpdatePropertyInstanceID, property)); Writer.WriteGuid(worldObject.Guid); Writer.Write((uint)property); Writer.WriteGuid(instanceGuid); }
public static void RemoveProperty(this Biota biota, PropertyInstanceId property) { var result = biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property); if (result != null) { biota.BiotaPropertiesIID.Remove(result); DatabaseManager.Shard.RemoveEntity(result, null); } }
public static bool TryRemoveProperty(this Biota biota, PropertyInstanceId property, out BiotaPropertiesIID entity) { entity = biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property); if (entity != null) { biota.BiotaPropertiesIID.Remove(entity); entity.Object = null; return(true); } return(false); }
// BiotaPropertiesFriendList // BiotaPropertiesGenerator public static uint?GetProperty(this Biota biota, PropertyInstanceId property, ReaderWriterLockSlim rwLock) { rwLock.EnterReadLock(); try { return(biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property)?.Value); } finally { rwLock.ExitReadLock(); } }
public static void SetProperty(this Biota biota, PropertyInstanceId property, uint value) { var result = biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property); if (result != null) result.Value = value; else { var entity = new BiotaPropertiesIID { ObjectId = biota.Id, Type = (ushort)property, Value = value, Object = biota }; biota.BiotaPropertiesIID.Add(entity); } }
public static uint?GetProperty(this Weenie weenie, PropertyInstanceId property) { if (weenie.PropertiesIID == null) { return(null); } if (weenie.PropertiesIID.TryGetValue(property, out var value)) { return(value); } return(null); }
public static void SetProperty(this Biota biota, PropertyInstanceId property, uint value) { var result = biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property); if (result != null) { result.Value = value; } else { biota.BiotaPropertiesIID.Add(new BiotaPropertiesIID { Type = (ushort)property, Value = value }); } }
public uint?GetProperty(PropertyInstanceId property) { BiotaDatabaseLock.EnterReadLock(); try { if (biotaPropertyInstanceIds.TryGetValue(property, out var record)) { return(record.Value); } return(null); } finally { BiotaDatabaseLock.ExitReadLock(); } }
public static bool TryRemoveProperty(this Biota biota, PropertyInstanceId property, ReaderWriterLockSlim rwLock) { if (biota.PropertiesIID == null) { return(false); } rwLock.EnterWriteLock(); try { return(biota.PropertiesIID.Remove(property)); } finally { rwLock.ExitWriteLock(); } }
public static void SetProperty(this Biota biota, PropertyInstanceId property, uint value, ReaderWriterLockSlim rwLock) { rwLock.EnterWriteLock(); try { if (biota.PropertiesIID == null) { biota.PropertiesIID = new Dictionary <PropertyInstanceId, uint>(); } biota.PropertiesIID[property] = value; } finally { rwLock.ExitWriteLock(); } }
public static uint?GetProperty(this Biota biota, PropertyInstanceId property, ReaderWriterLockSlim rwLock) { if (biota.PropertiesIID == null) { return(null); } rwLock.EnterReadLock(); try { if (biota.PropertiesIID.TryGetValue(property, out var value)) { return(value); } return(null); } finally { rwLock.ExitReadLock(); } }
public static void SetProperty(this Biota biota, PropertyInstanceId property, uint value, ReaderWriterLockSlim rwLock, out bool changed) { rwLock.EnterWriteLock(); try { if (biota.PropertiesIID == null) { biota.PropertiesIID = new Dictionary <PropertyInstanceId, uint>(); } changed = (!biota.PropertiesIID.TryGetValue(property, out var existing) || value != existing); if (changed) { biota.PropertiesIID[property] = value; } } finally { rwLock.ExitWriteLock(); } }
public static uint? GetProperty(this Biota biota, PropertyInstanceId property) { return biota.BiotaPropertiesIID.FirstOrDefault(x => x.Type == (uint)property)?.Value; }
public GameMessageUpdateInstanceId(SequenceManager sequences, ObjectGuid senderGuid, PropertyInstanceId idPropertyId, ObjectGuid value) : base(GameMessageOpcode.UpdateInstanceId, GameMessageGroup.Group09) { Writer.Write(sequences.GetNextSequence(SequenceType.PublicUpdatePropertyInstanceId)); // wts Writer.Write(senderGuid.Full); Writer.Write((uint)idPropertyId); Writer.Write(value.Full); }
/// <summary> /// This method is used to pick items off the world - out of 3D space and into our inventory or to a wielded slot. /// It checks the use case needed, sends the appropriate response messages. In addition, it will move to objects /// that are out of range in the attemp to pick them up. It will call update apperiance if needed and you have /// wielded an item from the ground. Og II /// </summary> /// <param name="container"></param> /// <param name="itemGuid"></param> /// <param name="placement"></param> /// <param name="iidPropertyId"></param> private void PickupItem(Container container, ObjectGuid itemGuid, int placement, PropertyInstanceId iidPropertyId) { // Logical operations: // !! FIXME: How to handle repeat on condition? // while (!objectInRange) // try Move to object // !! FIXME: How to handle conditional // Try acquire from landblock // if acquire successful: // add to container ActionChain pickUpItemChain = new ActionChain(); // Move to the object pickUpItemChain.AddChain(CreateMoveToChain(itemGuid, PickUpDistance)); // Pick up the object // Start pickup animation pickUpItemChain.AddAction(this, () => { var motion = new UniversalMotion(MotionStance.Standing); motion.MovementData.ForwardCommand = (uint)MotionCommand.Pickup; CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageUpdatePosition(this), new GameMessageUpdateMotion(Guid, Sequences.GetCurrentSequence(SequenceType.ObjectInstance), Sequences, motion)); }); // Wait for animation to progress var motionTable = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId); var pickupAnimationLength = motionTable.GetAnimationLength(MotionCommand.Pickup); pickUpItemChain.AddDelaySeconds(pickupAnimationLength); // Ask landblock to transfer item // pickUpItemChain.AddAction(CurrentLandblock, () => CurrentLandblock.TransferItem(itemGuid, containerGuid)); if (container.Guid.IsPlayer()) { CurrentLandblock.QueueItemTransfer(pickUpItemChain, itemGuid, container.Guid); } else { CurrentLandblock.ScheduleItemTransferInContainer(pickUpItemChain, itemGuid, (Container)GetInventoryItem(container.Guid)); } // Finish pickup animation pickUpItemChain.AddAction(this, () => { // If success, the item is in our inventory: WorldObject item = GetInventoryItem(itemGuid); if (item.ContainerId != Guid.Full) { //Burden += item.Burden ?? 0; if (item.WeenieType == WeenieType.Coin) { UpdateCurrencyClientCalculations(WeenieType.Coin); } } if (item is Container itemAsContainer) { Session.Network.EnqueueSend(new GameEventViewContents(Session, itemAsContainer)); foreach (var packItem in itemAsContainer.Inventory) { Session.Network.EnqueueSend(new GameMessageCreateObject(packItem.Value)); UpdateCurrencyClientCalculations(WeenieType.Coin); } } // Update all our stuff if we succeeded if (item != null) { item.SetPropertiesForContainer(placement); // FIXME(ddevec): I'm not 100% sure which of these need to be broadcasts, and which are local sends... var motion = new UniversalMotion(MotionStance.Standing); if (iidPropertyId == PropertyInstanceId.Container) { Session.Network.EnqueueSend( ////new GameMessagePrivateUpdatePropertyInt(Session.Player.Sequences, PropertyInt.EncumbranceVal, UpdateBurden()), new GameMessageSound(Guid, Sound.PickUpItem, 1.0f), new GameMessageUpdateInstanceId(itemGuid, container.Guid, iidPropertyId), new GameMessagePutObjectInContainer(Session, container.Guid, item, placement)); } else { AddToWieldedObjects(item, container, (EquipMask)placement); Session.Network.EnqueueSend(new GameMessageSound(Guid, Sound.WieldObject, (float)1.0), new GameMessageObjDescEvent(this), new GameMessageUpdateInstanceId(container.Guid, itemGuid, PropertyInstanceId.Wielder), new GameEventWieldItem(Session, itemGuid.Full, placement)); } CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageUpdateMotion(Guid, Sequences.GetCurrentSequence(SequenceType.ObjectInstance), Sequences, motion), new GameMessagePickupEvent(item)); if (iidPropertyId == PropertyInstanceId.Wielder) { CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageObjDescEvent(this)); } // TODO: Og II - check this later to see if it is still required. Session.Network.EnqueueSend(new GameMessageUpdateObject(item)); } // If we didn't succeed, just stand up and be ashamed of ourself else { var motion = new UniversalMotion(MotionStance.Standing); CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageUpdateMotion(Guid, Sequences.GetCurrentSequence(SequenceType.ObjectInstance), Sequences, motion)); // CurrentLandblock.EnqueueBroadcast(self shame); } }); // Set chain to run pickUpItemChain.EnqueueChain(); }
public static string GetDescription(this PropertyInstanceId prop) { var description = prop.GetAttributeOfType <DescriptionAttribute>(); return(description?.Description ?? prop.ToString()); }
public byte[] GetCurrentSequence(SequenceType type, PropertyInstanceId property) { return(GetSequence(type, (uint)property).CurrentBytes); }
public uint?GetProperty(PropertyInstanceId property) { return(Biota.GetProperty(property, BiotaDatabaseLock)); }
public GameMessageUpdateInstanceId(ObjectGuid containerGuid, ObjectGuid itemGuid, PropertyInstanceId iidPropertyId) : base(GameMessageOpcode.UpdateInstanceId, GameMessageGroup.Group09) { // TODO: research - could these types of sends be generalized by payload type? for example GameMessageInt Writer.Write((byte)1); // wts Writer.Write(containerGuid.Full); // sender Writer.Write((uint)iidPropertyId); Writer.Write(itemGuid.Full); // new value of the container id Writer.Align(); // not sure that I need this - can someone explain when to use this? }
// WeeniePropertiesGenerator public static uint?GetProperty(this Weenie weenie, PropertyInstanceId property) { return(weenie.WeeniePropertiesIID.FirstOrDefault(x => x.Type == (uint)property)?.Value); }
// ===================================== // Helper Functions - Inventory Movement // ===================================== // Used by HandleActionPutItemInContainer, HandleActionDropItem /// <summary> /// This method is used to pick items off the world - out of 3D space and into our inventory or to a wielded slot. /// It checks the use case needed, sends the appropriate response messages. /// In addition, it will move to objects that are out of range in the attemp to pick them up. /// It will call update apperiance if needed and you have wielded an item from the ground. Og II /// </summary> private void PickupItemWithNetworking(Container container, ObjectGuid itemGuid, int placementPosition, PropertyInstanceId iidPropertyId) { ActionChain pickUpItemChain = new ActionChain(); // Move to the object pickUpItemChain.AddChain(CreateMoveToChain(itemGuid, PickUpDistance)); // Pick up the object // Start pickup animation pickUpItemChain.AddAction(this, () => { var motion = new UniversalMotion(MotionStance.Standing); motion.MovementData.ForwardCommand = (uint)MotionCommand.Pickup; CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageUpdatePosition(this), new GameMessageUpdateMotion(Guid, Sequences.GetCurrentSequence(SequenceType.ObjectInstance), Sequences, motion)); }); // Wait for animation to progress var motionTable = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId); var pickupAnimationLength = motionTable.GetAnimationLength(MotionCommand.Pickup); pickUpItemChain.AddDelaySeconds(pickupAnimationLength); // Grab a reference to the item before its removed from the CurrentLandblock var item = CurrentLandblock.GetObject(itemGuid); // Queue up an action that wait for the landblock to remove the item. The action that gets queued, when fired, will be run on the landblocks ActionChain, not this players. CurrentLandblock.QueueItemRemove(pickUpItemChain, itemGuid); // Finish pickup animation pickUpItemChain.AddAction(this, () => { // If the item still has a location, CurrentLandblock failed to remove it if (item.Location != null) { log.Error("Player_Inventory PickupItemWithNetworking item.Location != null"); return; } // If the item has a ContainerId, it was probably picked up by someone else before us if (item.ContainerId != null && item.ContainerId != 0) { log.Error("Player_Inventory PickupItemWithNetworking item.ContainerId != 0"); return; } item.SetPropertiesForContainer(); // FIXME(ddevec): I'm not 100% sure which of these need to be broadcasts, and which are local sends... if (iidPropertyId == PropertyInstanceId.Container) { if (!container.TryAddToInventory(item, placementPosition, true)) { log.Error("Player_Inventory PickupItemWithNetworking TryAddToInventory failed"); return; } // If we've put the item to a side pack, we must increment our main EncumbranceValue and Value if (container != this) { EncumbranceVal += item.EncumbranceVal; Value += item.Value; // todo CoinValue } if (item is Container itemAsContainer) { Session.Network.EnqueueSend(new GameEventViewContents(Session, itemAsContainer)); foreach (var packItem in itemAsContainer.Inventory) { Session.Network.EnqueueSend(new GameMessageCreateObject(packItem.Value)); } } Session.Network.EnqueueSend( new GameMessageSound(Guid, Sound.PickUpItem, 1.0f), new GameMessageUpdateInstanceId(itemGuid, container.Guid, iidPropertyId), new GameMessagePutObjectInContainer(Session, container.Guid, item, placementPosition)); } else if (iidPropertyId == PropertyInstanceId.Wielder) { if (!TryEquipObject(item, placementPosition)) { log.Error("Player_Inventory PickupItemWithNetworking TryEquipObject failed"); return; } if (((EquipMask)placementPosition & EquipMask.Selectable) != 0) { SetChild(item, placementPosition, out _, out _); } // todo I think we need to recalc our SetupModel here. see CalculateObjDesc() Session.Network.EnqueueSend( new GameMessageSound(Guid, Sound.WieldObject, (float)1.0), new GameMessageObjDescEvent(this), new GameMessageUpdateInstanceId(container.Guid, itemGuid, PropertyInstanceId.Wielder), new GameEventWieldItem(Session, itemGuid.Full, placementPosition)); } Session.Network.EnqueueSend(new GameMessagePrivateUpdatePropertyInt(Session.Player.Sequences, PropertyInt.EncumbranceVal, EncumbranceVal ?? 0)); var motion = new UniversalMotion(MotionStance.Standing); CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageUpdateMotion(Guid, Sequences.GetCurrentSequence(SequenceType.ObjectInstance), Sequences, motion), new GameMessagePickupEvent(item)); if (iidPropertyId == PropertyInstanceId.Wielder) { CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageObjDescEvent(this)); } // TODO: Og II - check this later to see if it is still required. Session.Network.EnqueueSend(new GameMessageUpdateObject(item)); // Was Item controlled by a generator? // TODO: Should this be happening this way? Should the landblock notify the object of pickup or the generator... /*if (item.GeneratorId > 0) * { * WorldObject generator = GetObject(new ObjectGuid((uint)item.GeneratorId)); * * item.GeneratorId = null; * * generator.NotifyGeneratorOfPickup(item.Guid.Full); * }*/ item.SaveBiotaToDatabase(); }); // Set chain to run pickUpItemChain.EnqueueChain(); }