public static void HandleCIRandom(Session session, params string[] parameters) { uint typeId; byte numItems = 10; try { typeId = Convert.ToUInt32(parameters[0]); } catch (Exception) { ChatPacket.SendServerMessage(session, "Not a valid type id - must be a number between 0 - 2,147,483,647", ChatMessageType.Broadcast); return; } if (parameters.Length == 2) { try { numItems = Convert.ToByte(parameters[1]); } catch (Exception) { ChatPacket.SendServerMessage(session, "Not a valid number - must be a number between 0 - 50", ChatMessageType.Broadcast); return; } } LootGenerationFactory.CreateRandomTestWorldObjects(session.Player, typeId, numItems); }
public static void HandleSplits(Session session, params string[] parameters) { HashSet <uint> splitsTest = new HashSet <uint>() { 237, 300, 690, 20630, 20631, 37155, 31198 }; ActionChain chain = new ActionChain(); chain.AddAction(session.Player, () => { foreach (uint weenieId in splitsTest) { WorldObject loot = LootGenerationFactory.CreateTestWorldObject(session.Player, weenieId); var valueEach = loot.Value / loot.StackSize; loot.StackSize = loot.MaxStackSize; loot.Value = loot.StackSize * valueEach; loot.ContainerId = session.Player.Guid.Full; session.Player.AddToInventory(loot); session.Player.TrackObject(loot); session.Network.EnqueueSend( new GameMessagePutObjectInContainer(session, session.Player.Guid, loot, 0), new GameMessageUpdateInstanceId(loot.Guid, session.Player.Guid, PropertyInstanceId.Container)); } }); chain.EnqueueChain(); }
public static void SetCommonProperties(WorldObject source, WorldObject target) { // a lot of this was probably done with recipes and mutations in the original // here a lot is done directly in code.. target.PaletteTemplate = source.PaletteTemplate; if (PropertyManager.GetBool("tailoring_intermediate_uieffects").Item) { target.UiEffects = source.UiEffects; } target.MaterialType = source.MaterialType; target.ObjScale = source.ObjScale; target.Shade = source.Shade; // This might not even be needed, but we'll do it anyways target.Shade2 = source.Shade2; target.Shade3 = source.Shade3; target.Shade4 = source.Shade4; target.SetupTableId = source.SetupTableId; target.PaletteBaseId = source.PaletteBaseId; target.ClothingBase = source.ClothingBase; target.PhysicsTableId = source.PhysicsTableId; target.SoundTableId = source.SoundTableId; target.Name = source.Name; target.LongDesc = LootGenerationFactory.GetLongDesc(target); target.IgnoreCloIcons = source.IgnoreCloIcons; target.IconId = source.IconId; }
public static void CreateTrainingWand(Session session, params string[] parameters) { if (!(parameters?.Length > 0)) { ChatPacket.SendServerMessage(session, "Usage: @ctw me or @ctw ground", ChatMessageType.Broadcast); return; } string location = parameters[0]; if (location == "me" | location == "ground") { var loot = LootGenerationFactory.CreateTrainingWand(session.Player); switch (location) { case "me": { LootGenerationFactory.AddToContainer(loot, session.Player); break; } case "ground": { LootGenerationFactory.Spawn(loot, session.Player.Location.InFrontOf(1.0f)); break; } } session.Player.TrackObject(loot); } else { ChatPacket.SendServerMessage(session, "Usage: @ctw me or @ctw ground", ChatMessageType.Broadcast); } }
public static void HandleCIRandom(Session session, params string[] parameters) { string weenieTypeName = parameters[0]; bool isNumericType = uint.TryParse(weenieTypeName, out uint weenieTypeNumber); if (!isNumericType) { try { weenieTypeNumber = (uint)Enum.Parse(typeof(WeenieType), weenieTypeName); } catch { ChatPacket.SendServerMessage(session, "Not a valid type name", ChatMessageType.Broadcast); return; } } if (weenieTypeNumber == 0) { ChatPacket.SendServerMessage(session, "Not a valid type id - must be a number between 0 - 2,147,483,647", ChatMessageType.Broadcast); return; } byte numItems = 10; if (parameters.Length == 2) { try { numItems = Convert.ToByte(parameters[1]); if (numItems < 1) { numItems = 1; } if (numItems > 50) { numItems = 50; } } catch (Exception) { ChatPacket.SendServerMessage(session, "Not a valid number - must be a number between 1 - 50", ChatMessageType.Broadcast); return; } } var items = LootGenerationFactory.CreateRandomObjectsOfType((WeenieType)weenieTypeNumber, numItems); foreach (var item in items) { session.Player.TryCreateInInventoryWithNetworking(item); } }
public static void MoveTo(Session session, params string[] parameters) { var distance = 10.0f; ushort trainingWandTarget = 12748; if ((parameters?.Length > 0)) { distance = Convert.ToInt16(parameters[0]); } WorldObject loot = WorldObjectFactory.CreateNewWorldObject(trainingWandTarget); LootGenerationFactory.Spawn(loot, session.Player.Location.InFrontOf(distance)); session.Player.PutItemInContainer(loot.Guid, session.Player.Guid); }
public static void MoveTo(Session session, params string[] parameters) { var distance = 10.0f; if ((parameters?.Length > 0)) { distance = Convert.ToInt16(parameters[0]); } var loot = LootGenerationFactory.CreateTrainingWand(session.Player); LootGenerationFactory.Spawn(loot, session.Player.Location.InFrontOf(distance)); session.Player.TrackObject(loot); var newMotion = new UniversalMotion(MotionStance.Standing, loot); session.Network.EnqueueSend(new GameMessageUpdatePosition(session.Player)); session.Network.EnqueueSend(new GameMessageUpdateMotion(session.Player, loot, newMotion, MovementTypes.MoveToObject)); }
public static void MoveTo(Session session, params string[] parameters) { var distance = 10.0f; ushort trainingWandTarget = 12748; if ((parameters?.Length > 0)) { distance = Convert.ToInt16(parameters[0]); } var loot = LootGenerationFactory.CreateTestWorldObject(trainingWandTarget); LootGenerationFactory.Spawn(loot, session.Player.Location.InFrontOf(distance)); session.Player.TrackObject(loot); var newMotion = new UniversalMotion(MotionStance.Standing, loot.PhysicsData.Position, loot.Guid); newMotion.MovementTypes = MovementTypes.MoveToObject; session.Network.EnqueueSend(new GameMessageUpdatePosition(session.Player)); session.Network.EnqueueSend(new GameMessageUpdateMotion(session.Player.Guid, session.Player.Sequences.GetCurrentSequence(Network.Sequence.SequenceType.ObjectInstance), session.Player.Sequences, newMotion)); }
public static void MoveTo(Session session, params string[] parameters) { var distance = 10.0f; ushort trainingWandTarget = 12748; if ((parameters?.Length > 0)) { distance = Convert.ToInt16(parameters[0]); } WorldObject loot = WorldObjectFactory.CreateNewWorldObject(trainingWandTarget); ActionChain chain = new Entity.Actions.ActionChain(); // By chaining the spawn followed by the add pickup action, we ensure the item will be spawned before the player chain.AddChain(LootGenerationFactory.GetSpawnChain(loot, session.Player.Location.InFrontOf(distance))); chain.AddAction(session.Player, () => session.Player.HandleActionPutItemInContainer(loot.Guid, session.Player.Guid)); chain.EnqueueChain(); }
public static void HandleWeapons(Session session, params string[] parameters) { HashSet <uint> weaponsTest = new HashSet <uint>() { 93, 127, 130, 136, 136, 136, 148, 300, 307, 311, 326, 338, 348, 350, 7765, 12748, 12463, 31812 }; ActionChain chain = new ActionChain(); chain.AddAction(session.Player, () => { foreach (uint weenieId in weaponsTest) { WorldObject loot = LootGenerationFactory.CreateTestWorldObject(session.Player, weenieId); loot.ContainerId = session.Player.Guid.Full; session.Player.AddToInventory(loot); session.Player.TrackObject(loot); session.Player.UpdatePlayerBurden(); session.Network.EnqueueSend( new GameMessagePutObjectInContainer(session, session.Player.Guid, loot, 0), new GameMessageUpdateInstanceId(loot.Guid, session.Player.Guid, PropertyInstanceId.Container)); } }); chain.EnqueueChain(); }
/// <summary> /// Called every ~5 secs for equipped mana consuming items /// </summary> public void ManaConsumersTick() { if (!EquippedObjectsLoaded) { return; } var EquippedManaConsumers = EquippedObjects.Where(k => (k.Value.IsAffecting ?? false) && //k.Value.ManaRate.HasValue && k.Value.ItemMaxMana.HasValue && k.Value.ItemCurMana.HasValue && k.Value.ItemCurMana.Value > 0).ToList(); foreach (var k in EquippedManaConsumers) { var item = k.Value; // this was a bug in lootgen until 7/11/2019, mostly for clothing/armor/shields // tons of existing items on servers are in this bugged state, where they aren't ticking mana. // this retroactively fixes them when equipped // items such as Impious Staff are excluded from this via IsAffecting if (item.ManaRate == null) { item.ManaRate = LootGenerationFactory.GetManaRate(item); log.Warn($"{Name}.ManaConsumersTick(): {k.Value.Name} ({k.Value.Guid}) fixed missing ManaRate"); } var rate = item.ManaRate.Value; if (LumAugItemManaUsage != 0) { rate *= GetNegativeRatingMod(LumAugItemManaUsage * 5); } if (!item.ItemManaConsumptionTimestamp.HasValue) { item.ItemManaConsumptionTimestamp = DateTime.UtcNow; } DateTime mostRecentBurn = item.ItemManaConsumptionTimestamp.Value; var timePerBurn = -1 / rate; var secondsSinceLastBurn = (DateTime.UtcNow - mostRecentBurn).TotalSeconds; var delta = secondsSinceLastBurn / timePerBurn; var deltaChopped = (int)Math.Floor(delta); var deltaExtra = delta - deltaChopped; if (deltaChopped <= 0) { continue; } var timeToAdd = (int)Math.Floor(deltaChopped * timePerBurn); item.ItemManaConsumptionTimestamp = mostRecentBurn + new TimeSpan(0, 0, timeToAdd); var manaToBurn = Math.Min(item.ItemCurMana.Value, deltaChopped); deltaChopped = Math.Clamp(deltaChopped, 0, 10); item.ItemCurMana -= deltaChopped; if (item.ItemCurMana < 1 || item.ItemCurMana == null) { item.IsAffecting = false; var msg = new GameMessageSystemChat($"Your {item.Name} is out of Mana.", ChatMessageType.Magic); var sound = new GameMessageSound(Guid, Sound.ItemManaDepleted); Session.Network.EnqueueSend(msg, sound); if (item.WielderId != null) { if (item.Biota.PropertiesSpellBook != null) { // unsure if these messages / sounds were ever sent in retail, // or if it just purged the enchantments invisibly // doing a delay here to prevent 'SpellExpired' sounds from overlapping with 'ItemManaDepleted' var actionChain = new ActionChain(); actionChain.AddDelaySeconds(2.0f); actionChain.AddAction(this, () => { foreach (var spellId in item.Biota.GetKnownSpellsIds(item.BiotaDatabaseLock)) { RemoveItemSpell(item, (uint)spellId); } }); actionChain.EnqueueChain(); } } } else { // get time until empty var secondsUntilEmpty = ((item.ItemCurMana - deltaExtra) * timePerBurn); if (secondsUntilEmpty <= 120 && (!item.ItemManaDepletionMessageTimestamp.HasValue || (DateTime.UtcNow - item.ItemManaDepletionMessageTimestamp.Value).TotalSeconds > 120)) { item.ItemManaDepletionMessageTimestamp = DateTime.UtcNow; Session.Network.EnqueueSend(new GameMessageSystemChat($"Your {item.Name} is low on Mana.", ChatMessageType.Magic)); } } } }
private void HandleGameAction(QueuedGameAction action, Player player) { switch (action.ActionType) { case GameActionType.TalkDirect: { // TODO: remove this hack (using TalkDirect) ASAP var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } DeathMessageArgs d = new DeathMessageArgs(action.ActionBroadcastMessage, new ObjectGuid(action.ObjectId), new ObjectGuid(action.SecondaryObjectId)); HandleDeathMessage(obj, d); break; } case GameActionType.TeleToHouse: case GameActionType.TeleToLifestone: case GameActionType.TeleToMansion: case GameActionType.TeleToMarketPlace: case GameActionType.TeleToPkArena: case GameActionType.TeleToPklArena: { player.Teleport(action.ActionLocation); break; } case GameActionType.ApplyVisualEffect: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var particleEffect = (PlayScript)action.SecondaryObjectId; HandleParticleEffectEvent(obj, particleEffect); break; } case GameActionType.ApplySoundEffect: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var soundEffect = (Sound)action.SecondaryObjectId; HandleSoundEvent(obj, soundEffect); break; } case GameActionType.IdentifyObject: { // TODO: Throttle this request. The live servers did this, likely for a very good reason, so we should, too. var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var identifyResponse = new GameEventIdentifyObjectResponse(player.Session, action.ObjectId, obj); player.Session.Network.EnqueueSend(identifyResponse); break; } case GameActionType.Buy: { // todo: lots, need vendor list, money checks, etc. var money = new GameMessagePrivateUpdatePropertyInt(player.Session, PropertyInt.CoinValue, 4000); var sound = new GameMessageSound(player.Guid, Sound.PickUpItem, 1); var sendUseDoneEvent = new GameEventUseDone(player.Session); player.Session.Network.EnqueueSend(money, sound, sendUseDoneEvent); // send updated vendor inventory. player.Session.Network.EnqueueSend(new GameEventApproachVendor(player.Session, action.ObjectId)); // this is just some testing code for now. foreach (ItemProfile item in action.ProfileItems) { // todo: something with vendor id and profile list... iid list from vendor dbs. // todo: something with amounts.. if (item.Iid == 5) { while (item.Amount > 0) { item.Amount--; WorldObject loot = LootGenerationFactory.CreateTestWorldObject(5090); LootGenerationFactory.AddToContainer(loot, player); player.TrackObject(loot); } var rudecomment = "Who do you think you are, Johny Apple Seed ?"; var buyrudemsg = new GameMessageSystemChat(rudecomment, ChatMessageType.Tell); player.Session.Network.EnqueueSend(buyrudemsg); } else if (item.Iid == 10) { while (item.Amount > 0) { item.Amount--; WorldObject loot = LootGenerationFactory.CreateTestWorldObject(30537); LootGenerationFactory.AddToContainer(loot, player); player.TrackObject(loot); } var rudecomment = "That smells awful, Enjoy eating it!"; var buyrudemsg = new GameMessageSystemChat(rudecomment, ChatMessageType.Tell); player.Session.Network.EnqueueSend(buyrudemsg); } } break; } case GameActionType.PutItemInContainer: { var playerGuid = new ObjectGuid(action.ObjectId); var inventoryGuid = new ObjectGuid(action.SecondaryObjectId); // Has to be a player so need to check before I make the cast. // If he is not a player, something is bad wrong. Og II if (playerGuid.IsPlayer()) { var aPlayer = (Player)GetWorldObject(playerGuid); var inventoryItem = GetWorldObject(inventoryGuid); float arrivedRadiusSquared = 0.00f; bool validGuids; if (WithinUseRadius(playerGuid, inventoryGuid, out arrivedRadiusSquared, out validGuids)) { aPlayer.NotifyAndAddToInventory(inventoryItem); } else { if (validGuids) { aPlayer.SetDestinationInformation(inventoryItem.PhysicsData.Position, arrivedRadiusSquared); aPlayer.BlockedGameAction = action; aPlayer.OnAutonomousMove(inventoryItem.PhysicsData.Position, aPlayer.Sequences, MovementTypes.MoveToObject, inventoryGuid); } } } break; } case GameActionType.DropItem: { var g = new ObjectGuid(action.ObjectId); if (worldObjects.ContainsKey(g)) { var playerId = new ObjectGuid(action.ObjectId); var inventoryId = new ObjectGuid(action.SecondaryObjectId); if (playerId.IsPlayer()) { var aPlayer = (Player)worldObjects[playerId]; aPlayer.NotifyAndDropItem(inventoryId); } } break; } case GameActionType.MovementEvent: { var g = new ObjectGuid(action.ObjectId); WorldObject obj = (WorldObject)player; if (worldObjects.ContainsKey(g)) { obj = worldObjects[g]; } var motion = action.Motion; HandleMovementEvent(obj, motion); break; } case GameActionType.ObjectCreate: { AddWorldObject(action.WorldObject); break; } case GameActionType.ObjectDelete: { RemoveWorldObject(action.WorldObject.Guid, false); break; } case GameActionType.QueryHealth: { if (action.ObjectId == 0) { // Deselect the formerly selected Target player.SelectedTarget = 0; break; } object target = null; var targetId = new ObjectGuid(action.ObjectId); // Remember the selected Target player.SelectedTarget = action.ObjectId; // TODO: once items are implemented check if there are items that can trigger // the QueryHealth event. So far I believe it only gets triggered for players and creatures if (targetId.IsPlayer() || targetId.IsCreature()) { if (worldObjects.ContainsKey(targetId)) { target = worldObjects[targetId]; } if (target == null) { // check adjacent landblocks for the targetId foreach (var block in adjacencies) { if (block.Value != null) { if (block.Value.worldObjects.ContainsKey(targetId)) { target = block.Value.worldObjects[targetId]; } } } } if (target != null) { float healthPercentage = 0; if (targetId.IsPlayer()) { Player tmpTarget = (Player)target; healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue; } if (targetId.IsCreature()) { Creature tmpTarget = (Creature)target; healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue; } var updateHealth = new GameEventUpdateHealth(player.Session, targetId.Full, healthPercentage); player.Session.Network.EnqueueSend(updateHealth); } } break; } case GameActionType.Use: { var g = new ObjectGuid(action.ObjectId); if (worldObjects.ContainsKey(g)) { WorldObject obj = worldObjects[g]; if ((obj.DescriptionFlags & ObjectDescriptionFlag.LifeStone) != 0) { (obj as Lifestone).OnUse(player); } else if ((obj.DescriptionFlags & ObjectDescriptionFlag.Portal) != 0) { // TODO: When Physics collisions are implemented, this logic should be switched there, as normal portals are not onUse. (obj as Portal).OnCollide(player); } else if ((obj.DescriptionFlags & ObjectDescriptionFlag.Door) != 0) { (obj as Door).OnUse(player); } else if ((obj.DescriptionFlags & ObjectDescriptionFlag.Vendor) != 0) { (obj as Vendor).OnUse(player); } // switch (obj.Type) // { // case Enum.ObjectType.Portal: // { // // TODO: When Physics collisions are implemented, this logic should be switched there, as normal portals are not onUse. // // (obj as Portal).OnCollide(player); // // break; // } // case Enum.ObjectType.LifeStone: // { // (obj as Lifestone).OnUse(player); // break; // } // } } break; } } }
private void CreateCorpse() { if (NoCorpse ?? false) { return; } var corpse = WorldObjectFactory.CreateNewWorldObject(DatabaseManager.World.GetCachedWeenie("corpse")) as Corpse; corpse.SetupTableId = SetupTableId; corpse.MotionTableId = MotionTableId; corpse.SoundTableId = SoundTableId; corpse.PaletteBaseDID = PaletteBaseDID; corpse.ClothingBase = ClothingBase; corpse.PhysicsTableId = PhysicsTableId; if (ObjScale.HasValue) { corpse.ObjScale = ObjScale; } if (PaletteTemplate.HasValue) { corpse.PaletteTemplate = PaletteTemplate; } if (Shade.HasValue) { corpse.Shade = Shade; } //if (Translucency.HasValue) // Shadows have Translucency but their corpses do not, videographic evidence can be found on YouTube. // corpse.Translucency = Translucency; if (EquippedObjects.Values.Where(x => (x.CurrentWieldedLocation & (EquipMask.Clothing | EquipMask.Armor | EquipMask.Cloak)) != 0).ToList().Count > 0) // If creature is wearing objects, we need to save the appearance { var objDesc = CalculateObjDesc(); foreach (var animPartChange in objDesc.AnimPartChanges) { corpse.Biota.BiotaPropertiesAnimPart.Add(new Database.Models.Shard.BiotaPropertiesAnimPart { ObjectId = corpse.Guid.Full, AnimationId = animPartChange.PartID, Index = animPartChange.PartIndex }); } foreach (var subPalette in objDesc.SubPalettes) { corpse.Biota.BiotaPropertiesPalette.Add(new Database.Models.Shard.BiotaPropertiesPalette { ObjectId = corpse.Guid.Full, SubPaletteId = subPalette.SubID, Length = (ushort)subPalette.NumColors, Offset = (ushort)subPalette.Offset }); } foreach (var textureChange in objDesc.TextureChanges) { corpse.Biota.BiotaPropertiesTextureMap.Add(new Database.Models.Shard.BiotaPropertiesTextureMap { ObjectId = corpse.Guid.Full, Index = textureChange.PartIndex, OldId = textureChange.OldTexture, NewId = textureChange.NewTexture }); } } //corpse.Location = Location; corpse.Location = DatManager.PortalDat.ReadFromDat <MotionTable>(MotionTableId).GetAnimationFinalPositionFromStart(Location, ObjScale ?? 1, MotionCommand.Dead); //corpse.Location.PositionZ = corpse.Location.PositionZ - .5f; // Adding BaseDescriptionFlags |= ObjectDescriptionFlag.Corpse to Corpse objects made them immune to gravity.. this seems to fix floating corpse... corpse.Name = $"Corpse of {Name}"; string killerName = null; if (Killer.HasValue && Killer != 0) { var killer = CurrentLandblock.GetObject(new ObjectGuid(Killer ?? 0)); if (killer != null) { killerName = killer.Name; } } if (String.IsNullOrEmpty(killerName)) { killerName = "misadventure"; } corpse.LongDesc = $"Killed by {killerName}"; if (Killer.HasValue) { corpse.SetProperty(PropertyInstanceId.AllowedActivator, Killer.Value); // Think this will be what limits corpses to Killer first. } // Transfer of generated treasure from creature to corpse here var random = new Random((int)DateTime.UtcNow.Ticks); int level = (int)this.Level; int tier; if (level < 16) { tier = 1; } else if (level < 31) { tier = 2; } else if (level < 60) { tier = 3; } else if (level < 80) { tier = 4; } else if (level < 115) { tier = 5; } else if (level < 160) { tier = 6; } else { tier = 7; } ////Tier 8 is reserved for special creatures, usually based on which landblock they were on...Not level based. to be added later foreach (var trophy in Biota.BiotaPropertiesCreateList.Where(x => x.DestinationType == (int)DestinationType.Contain || x.DestinationType == (int)DestinationType.Treasure || x.DestinationType == (int)DestinationType.ContainTreasure || x.DestinationType == (int)DestinationType.ShopTreasure || x.DestinationType == (int)DestinationType.WieldTreasure).OrderBy(x => x.Shade)) { if (random.NextDouble() < trophy.Shade || trophy.Shade == 1 || trophy.Shade == 0) // Shade in this context is Probability // Should there be rolls for each item or one roll to rule them all? { if (trophy.WeenieClassId == 0) // Randomized Loot { var wo = LootGenerationFactory.CreateRandomLootObjects(tier); corpse.TryAddToInventory(wo); //var book = WorldObjectFactory.CreateNewWorldObject("parchment") as Book; //if (book == null) // continue; //book.SetProperties("IOU", "An IOU for a random loot.", "Sorry about that chief...", "ACEmulator", "prewritten"); //book.AddPage(corpse.Guid.Full, "ACEmulator", "prewritten", false, $"Sorry but at this time we do not have randomized and mutated loot in ACEmulator, you can ignore this item as it's meant only to be placeholder"); //corpse.TryAddToInventory(book); } else // Trophy Loot { var wo = WorldObjectFactory.CreateNewWorldObject(trophy.WeenieClassId); if (wo == null) { continue; } if (trophy.StackSize > 1) { wo.StackSize = (ushort)trophy.StackSize; } if (trophy.Palette > 0) { wo.PaletteTemplate = trophy.Palette; } corpse.TryAddToInventory(wo); } } } corpse.RemoveProperty(PropertyInt.Value); LandblockManager.AddObject(corpse); }
private void SetEphemeralValues() { //BaseDescriptionFlags |= ObjectDescriptionFlag.Door; //if (!DefaultOpen) //{ // CurrentMotionState = motionStateClosed; // IsOpen = false; // //Ethereal = false; //} //else //{ // CurrentMotionState = motionStateOpen; // IsOpen = true; // //Ethereal = true; //} ContainerCapacity = ContainerCapacity ?? 10; ItemCapacity = ItemCapacity ?? 120; //Adding loot to chests //Eventually these case statements would be linked to indivual treasure generators. Each one should be a different profile, but currently it will be the complete appropriate tier profile. for (int i = 0; i < GeneratorProfiles.Count; i++) { int amount = ThreadSafeRandom.Next(2, 14); //r.Next(2, 14); var generator = GeneratorProfiles[i]; switch (generator.Biota.WeenieClassId) { case 414: case 459: case 0: case 6: case 18: case 465: for (int j = 0; j < amount; j++) { var wo = LootGenerationFactory.CreateRandomLootObjects(1); TryAddToInventory(wo); } break; case 413: case 410: case 16: case 457: case 4: case 463: case 395: for (int j = 0; j < amount; j++) { var wo = LootGenerationFactory.CreateRandomLootObjects(2); TryAddToInventory(wo); } break; case 411: case 15: case 313: case 462: case 3: case 456: case 340: case 365: for (int j = 0; j < amount; j++) { var wo = LootGenerationFactory.CreateRandomLootObjects(3); TryAddToInventory(wo); } break; case 460: case 412: case 354: case 1: case 13: case 59: case 339: for (int j = 0; j < amount; j++) { var wo = LootGenerationFactory.CreateRandomLootObjects(4); TryAddToInventory(wo); } break; case 334: case 341: case 317: for (int j = 0; j < amount; j++) { var wo = LootGenerationFactory.CreateRandomLootObjects(5); TryAddToInventory(wo); } break; case 449: case 32: case 2: case 421: case 349: case 351: case 422: case 338: for (int j = 0; j < amount; j++) { var wo = LootGenerationFactory.CreateRandomLootObjects(6); TryAddToInventory(wo); } break; default: if (generator.Biota.WeenieClassId > 500) { //If the WeenieClassId is greater than the profile Id's, then it will be an item that is created with that Id. var wo = WorldObjectFactory.CreateNewWorldObject((uint)generator.Biota.WeenieClassId); TryAddToInventory(wo); } break; } } CurrentMotionState = motionClosed; // What chest defaults to open? if (UseRadius < 2) { UseRadius = 2; // Until DoMoveTo (Physics, Indoor/Outside range variance) is smarter, use 2 is safest. } }