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. } }