core(fix): Fixes type aliasing, categorizations, and NPE (#444)

- [X] Fixes lookup of type aliases
- [X] Fixes categorization
- [X] Removes rebuild categorizations
- [X] Fixes an NPE with DoHarmful and Combatant

Closes #441
This commit is contained in:
Kamron Batman 2021-02-03 16:14:04 -08:00 committed by GitHub
parent 24ebdd0f90
commit 5d9ebf062f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 3821 additions and 4881 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,508 +0,0 @@
[
{ "category": "Items", "types": ["Item"] },
{
"category": "Items.Bods & Rewards",
"types": [
"SmallBOD", "LargeBOD", "BulkOrderBook", "SturdyPickaxe", "SturdyShovel", "BaseGlovesOfMining",
"GargoylesPickaxe", "ProspectorsTool", "PowderOfTemperament", "ColoredAnvil", "RunicHammer",
"AncientSmithyHammer", "SmallStretchedHideEastDeed", "SmallStretchedHideEastAddon",
"SmallStretchedHideSouthDeed", "SmallStretchedHideSouthAddon", "MediumStretchedHideEastDeed",
"MediumStretchedHideEastAddon", "MediumStretchedHideSouthDeed", "MediumStretchedHideSouthAddon",
"LightFlowerTapestryEastDeed", "LightFlowerTapestryEastAddon", "LightFlowerTapestrySouthDeed",
"LightFlowerTapestrySouthAddon", "DarkFlowerTapestryEastDeed", "DarkFlowerTapestryEastAddon",
"DarkFlowerTapestrySouthDeed", "DarkFlowerTapestrySouthAddon", "BrownBearRugEastDeed",
"BrownBearRugEastAddon", "BrownBearRugSouthDeed", "BrownBearRugSouthAddon", "PolarBearRugEastDeed",
"PolarBearRugEastAddon", "PolarBearRugSouthDeed", "PolarBearRugSouthAddon", "ClothingBlessDeed",
"RunicSewingKit"
]
},
{
"category": "Items.Bods & Rewards.Smithing",
"types": [
"SmallSmithBOD", "LargeSmithBOD", "SturdyPickaxe", "SturdyShovel", "BaseGlovesOfMining",
"GargoylesPickaxe", "ProspectorsTool", "PowderOfTemperament", "ColoredAnvil", "RunicHammer",
"AncientSmithyHammer"
]
},
{
"category": "Items.Bods & Rewards.Tailoring",
"types": [
"SmallTailorBOD", "LargeTailorBOD", "SmallStretchedHideEastDeed", "SmallStretchedHideEastAddon",
"SmallStretchedHideSouthDeed", "SmallStretchedHideSouthAddon", "MediumStretchedHideEastDeed",
"MediumStretchedHideEastAddon", "MediumStretchedHideSouthDeed", "MediumStretchedHideSouthAddon",
"LightFlowerTapestryEastDeed", "LightFlowerTapestryEastAddon", "LightFlowerTapestrySouthDeed",
"LightFlowerTapestrySouthAddon", "DarkFlowerTapestryEastDeed", "DarkFlowerTapestryEastAddon",
"DarkFlowerTapestrySouthDeed", "DarkFlowerTapestrySouthAddon", "BrownBearRugEastDeed",
"BrownBearRugEastAddon", "BrownBearRugSouthDeed", "BrownBearRugSouthAddon", "PolarBearRugEastDeed",
"PolarBearRugEastAddon", "PolarBearRugSouthDeed", "PolarBearRugSouthAddon", "ClothingBlessDeed",
"RunicSewingKit"
]
},
{ "category": "Items.Bods & Rewards.Tailoring.Addons", "types": ["BaseAddon", "BaseAddonDeed"] },
{ "category": "Items.Bods & Rewards.Tailoring.Addons.Constructed", "types": ["BaseAddon"] },
{ "category": "Items.Bods & Rewards.Tailoring.Addons.Deeds", "types": ["BaseAddonDeed"] },
{
"category": "Items.Wearables",
"types": ["BaseArmor", "BaseClothing", "BaseSuit", "BaseJewel", "BaseWeapon"]
},
{ "category": "Items.Wearables.Armor", "types": ["BaseArmor"] },
{
"category": "Items.Wearables.Armor.Artifacts",
"types": [
"ArmorOfFortune", "GauntletsOfNobility", "HelmOfInsight", "HolyKnightsBreastplate",
"InquisitorsResolution", "JackalsCollar", "LeggingsOfBane", "MidnightBracers",
"OrnateCrownOfTheHarrower", "ShadowDancerLeggings", "TunicOfFire", "VoiceOfTheFallenKing"
]
},
{
"category": "Items.Wearables.Armor.Bone",
"types": ["BoneArms", "BoneChest", "BoneGloves", "BoneLegs", "BoneHelm"]
},
{ "category": "Items.Wearables.Armor.Chain", "types": ["ChainChest", "ChainLegs", "ChainCoif"] },
{
"category": "Items.Wearables.Armor.Daemon Bone",
"types": ["DaemonArms", "DaemonChest", "DaemonGloves", "DaemonLegs", "DaemonHelm"]
},
{
"category": "Items.Wearables.Armor.Dragon",
"types": ["DragonArms", "DragonChest", "DragonGloves", "DragonLegs", "DragonHelm"]
},
{
"category": "Items.Wearables.Armor.Helmets",
"types": ["Bascinet", "CloseHelm", "Helmet", "NorseHelm", "OrcHelm"]
},
{
"category": "Items.Wearables.Armor.Leather",
"types": [
"FemaleLeatherChest", "LeatherArms", "LeatherBustierArms", "LeatherChest", "LeatherGloves",
"LeatherGorget", "LeatherLegs", "LeatherShorts", "LeatherSkirt", "LeatherCap"
]
},
{
"category": "Items.Wearables.Armor.Plate",
"types": [
"FemalePlateChest", "PlateArms", "PlateChest", "PlateGloves", "PlateGorget", "PlateLegs",
"PlateHelm"
]
},
{
"category": "Items.Wearables.Armor.Ranger",
"types": ["RangerArms", "RangerChest", "RangerGloves", "RangerGorget", "RangerLegs"]
},
{
"category": "Items.Wearables.Armor.Ring",
"types": ["RingmailArms", "RingmailChest", "RingmailGloves", "RingmailLegs"]
},
{
"category": "Items.Wearables.Armor.Studded Leather",
"types": [
"FemaleStuddedChest", "StuddedArms", "StuddedBustierArms", "StuddedChest", "StuddedGloves",
"StuddedGorget", "StuddedLegs"
]
},
{ "category": "Items.Wearables.Armor.Shields", "types": ["BaseShield"] },
{ "category": "Items.Wearables.Armor.Shields.Artifacts", "types": ["Aegis", "ArcaneShield"] },
{ "category": "Items.Wearables.Weapons", "types": ["BaseWeapon"] },
{
"category": "Items.Wearables.Weapons.Artifacts",
"types": [
"AxeOfTheHeavens", "BladeOfInsanity", "BladeOfTheRighteous", "BoneCrusher", "BreathOfTheDead",
"Frostbringer", "LegacyOfTheDreadLord", "SerpentsFang", "StaffOfTheMagi", "TheBeserkersMaul",
"TheDragonSlayer", "TheTaskmaster", "TitansHammer", "ZyronicClaw"
]
},
{ "category": "Items.Wearables.Weapons.Wands", "types": ["BaseWand"] },
{ "category": "Items.Wearables.Weapons.Axes", "types": ["BaseAxe"] },
{ "category": "Items.Wearables.Weapons.Knives", "types": ["BaseKnife"] },
{ "category": "Items.Wearables.Weapons.Bashing", "types": ["BaseBashing"] },
{ "category": "Items.Wearables.Weapons.Pole Arms", "types": ["BasePoleArm"] },
{ "category": "Items.Wearables.Weapons.Ranged", "types": ["BaseRanged"] },
{ "category": "Items.Wearables.Weapons.Spears", "types": ["BaseSpear"] },
{ "category": "Items.Wearables.Weapons.Staves", "types": ["BaseStaff"] },
{ "category": "Items.Wearables.Weapons.Swords", "types": ["BaseSword"] },
{ "category": "Items.Wearables.Clothing", "types": ["BaseClothing"] },
{ "category": "Items.Wearables.Clothing.Cloaks", "types": ["BaseCloak"] },
{ "category": "Items.Wearables.Clothing.Hats", "types": ["BaseHat"] },
{ "category": "Items.Wearables.Clothing.Robes", "types": ["BaseOuterTorso"] },
{ "category": "Items.Wearables.Clothing.Shirts", "types": ["BaseShirt"] },
{ "category": "Items.Wearables.Clothing.Pants", "types": ["BasePants", "BaseOuterLegs"] },
{ "category": "Items.Wearables.Clothing.Shoes", "types": ["BaseShoes"] },
{ "category": "Items.Wearables.Clothing.Misc", "types": ["BaseWaist", "BaseMiddleTorso"] },
{ "category": "Items.Wearables.Jewelry", "types": ["BaseJewel"] },
{
"category": "Items.Wearables.Jewelry.Artifacts",
"types": ["BraceletOfHealth", "OrnamentOfTheMagician", "RingOfTheElements", "RingOfTheVile"]
},
{ "category": "Items.Wearables.Suits", "types": ["BaseSuit"] },
{ "category": "Items.Addons", "types": ["BaseAddonDeed", "BaseAddon"] },
{ "category": "Items.Addons.Constructed", "types": ["BaseAddon"] },
{
"category": "Items.Addons.Constructed.Smithing",
"types": [
"LargeForgeEastAddon", "LargeForgeSouthAddon", "SmallForgeAddon", "AnvilEastAddon",
"AnvilSouthAddon"
]
},
{
"category": "Items.Addons.Constructed.Tailoring",
"types": ["LoomEastAddon", "LoomSouthAddon", "SpinningWheelEastAddon", "SpinningWheelSouthAddon"]
},
{
"category": "Items.Addons.Constructed.Cooking",
"types": ["FlourMillEastAddon", "FlourMillSouthAddon", "StoneOvenEastAddon", "StoneOvenSouthAddon"]
},
{
"category": "Items.Addons.Constructed.Bedding",
"types": ["LargeBedEastAddon", "LargeBedSouthAddon", "SmallBedSouthAddon", "SmallBedEastAddon"]
},
{
"category": "Items.Addons.Constructed.Training",
"types": [
"TrainingDummyEastAddon", "TrainingDummySouthAddon", "PickpocketDipEastAddon",
"PickpocketDipSouthAddon", "ArcheryButteAddon"
]
},
{
"category": "Items.Addons.Constructed.Spiritual",
"types": ["PentagramAddon", "BloodPentagram", "AbbatoirAddon"]
},
{
"category": "Items.Addons.Constructed.Furniture",
"types": [
"LargeStoneTableEastAddon", "LargeStoneTableSouthAddon", "MediumStoneTableEastAddon",
"MediumStoneTableSouthAddon"
]
},
{ "category": "Items.Addons.Constructed.Misc", "types": ["BaseAddon"] },
{ "category": "Items.Addons.Deeds", "types": ["BaseAddonDeed"] },
{
"category": "Items.Addons.Deeds.Smithing",
"types": ["LargeForgeEastDeed", "LargeForgeSouthDeed", "SmallForgeDeed", "AnvilEastDeed", "AnvilSouthDeed"]
},
{
"category": "Items.Addons.Deeds.Tailoring",
"types": ["LoomEastDeed", "LoomSouthDeed", "SpinningWheelEastDeed", "SpinningWheelSouthDeed"]
},
{
"category": "Items.Addons.Deeds.Cooking",
"types": ["FlourMillEastDeed", "FlourMillSouthDeed", "StoneOvenEastDeed", "StoneOvenSouthDeed"]
},
{
"category": "Items.Addons.Deeds.Bedding",
"types": ["LargeBedEastDeed", "LargeBedSouthDeed", "SmallBedEastDeed", "SmallBedSouthDeed"]
},
{
"category": "Items.Addons.Deeds.Training",
"types": [
"TrainingDummyEastDeed", "TrainingDummySouthDeed", "PickpocketDipEastDeed", "PickpocketDipSouthDeed",
"ArcheryButteDeed"
]
},
{ "category": "Items.Addons.Deeds.Spiritual", "types": ["PentagramDeed", "AbbatoirDeed"] },
{
"category": "Items.Addons.Deeds.Furniture",
"types": [
"LargeStoneTableEastDeed", "LargeStoneTableSouthDeed", "MediumStoneTableEastDeed",
"MediumStoneTableSouthDeed"
]
},
{ "category": "Items.Addons.Deeds.Misc", "types": ["BaseAddonDeed"] },
{ "category": "Items.Books", "types": ["BaseBook"] },
{
"category": "Items.Resources",
"types": [
"BaseIngot", "BaseOre", "BaseGranite", "BaseScales", "BaseReagent", "BaseHides", "BaseLeather",
"Log", "Board", "BaseClothMaterial", "Bone", "UncutCloth", "BoltOfCloth", "Cloth", "Wool", "Flax",
"Cotton", "BagOfAllReagents", "BagOfNecroReagents", "BagOfReagents", "AlchemyBag", "BagOfIngots",
"ScribeBag", "SmithBag", "TailorBag", "Fish", "BigFish", "BaseMagicFish", "Arrow", "Bolt", "Feather",
"Shaft", "AlchemyStone", "IngotStone", "RegStone", "ScribeStone", "SmithStone", "TailorStone",
"Sand"
]
},
{ "category": "Items.Resources.Ingots", "types": ["BaseIngot"] },
{ "category": "Items.Resources.Ore", "types": ["BaseOre"] },
{ "category": "Items.Resources.Granite", "types": ["BaseGranite"] },
{ "category": "Items.Resources.Scales", "types": ["BaseScales"] },
{ "category": "Items.Resources.Reagents", "types": ["BaseReagent"] },
{
"category": "Items.Resources.Reagents.Standard",
"types": [
"BlackPearl", "Bloodmoss", "Garlic", "Ginseng", "MandrakeRoot", "Nightshade", "SpidersSilk",
"SulfurousAsh"
]
},
{
"category": "Items.Resources.Reagents.Necromancy",
"types": ["BatWing", "DaemonBlood", "GraveDust", "NoxCrystal", "PigIron"]
},
{ "category": "Items.Resources.Wood", "types": ["Log", "Board"] },
{ "category": "Items.Resources.Fish", "types": ["Fish", "BigFish", "BaseMagicFish"] },
{
"category": "Items.Resources.Tailoring",
"types": [
"BaseHides", "BaseLeather", "BaseClothMaterial", "Bone", "BoltOfCloth", "Cloth", "UncutCloth",
"Wool", "Flax", "Cotton"
]
},
{ "category": "Items.Resources.Tailoring.Hides", "types": ["BaseHides"] },
{ "category": "Items.Resources.Tailoring.Leather", "types": ["BaseLeather"] },
{ "category": "Items.Resources.Tailoring.Cloth", "types": ["BoltOfCloth", "Cloth", "UncutCloth"] },
{
"category": "Items.Resources.Tailoring.Materials",
"types": ["BaseClothMaterial", "Wool", "Flax", "Cotton"]
},
{ "category": "Items.Resources.Fletching", "types": ["Arrow", "Bolt", "Feather", "Shaft"] },
{
"category": "Items.Resources.Bags",
"types": [
"BagOfAllReagents", "BagOfNecroReagents", "BagOfReagents", "AlchemyBag", "BagOfIngots", "ScribeBag",
"SmithBag", "TailorBag"
]
},
{
"category": "Items.Resources.Stones",
"types": ["AlchemyStone", "IngotStone", "RegStone", "ScribeStone", "SmithStone", "TailorStone"]
},
{ "category": "Items.Entertainment", "types": ["BaseInstrument", "BaseBoard", "Dices"] },
{ "category": "Items.Entertainment.Instruments", "types": ["BaseInstrument"] },
{ "category": "Items.Entertainment.Games", "types": ["BaseBoard", "Dices"] },
{
"category": "Items.Construction",
"types": [
"BaseDoor", "BaseFloor", "Container", "DecorativeShield1", "DecorativeShield2", "DecorativeShield3",
"DecorativeShield4", "DecorativeShield5", "DecorativeShield6", "DecorativeShield7",
"DecorativeShield8", "DecorativeShield9", "DecorativeShield10", "DecorativeShield11",
"DecorativeShieldSword1North", "DecorativeShieldSword1West", "DecorativeShieldSword2North",
"DecorativeShieldSword2West", "DecorativeBowWest", "DecorativeBowNorth", "DecorativeAxeNorth",
"DecorativeAxeWest", "DecorativeSwordNorth", "DecorativeSwordWest", "DecorativeDAxeNorth",
"DecorativeDAxeWest", "LargePainting", "WomanPortrait1", "WomanPortrait2", "ManPortrait1",
"ManPortrait2", "LadyPortrait1", "LadyPortrait2", "Tapestry1N", "Tapestry2N", "Tapestry2W",
"Tapestry3N", "Tapestry3W", "Tapestry4N", "Tapestry4W", "Tapestry5N", "Tapestry5W", "Tapestry6N",
"Tapestry6W", "RuinedFallenChairA", "RuinedArmoire", "RuinedBookcase", "RuinedBooks", "CoveredChair",
"RuinedFallenChairB", "RuinedChair", "RuinedClock", "RuinedDrawers", "RuinedPainting", "WoodDebris",
"Rope", "IronWire", "SilverWire", "GoldWire", "CopperWire", "Whip", "PaintsAndBrush", "WoodenBench",
"FancyWoodenChairCushion", "WoodenChairCushion", "WoodenChair", "BambooChair", "Stool", "FootStool",
"Throne", "WoodenThrone", "LargeTable", "Nightstand", "YewWoodTable", "WritingTable", "Easel",
"TallMusicStand", "ShortMusicStand"
]
},
{
"category": "Items.Construction.Decoration",
"types": [
"DecorativeShield1", "DecorativeShield2", "DecorativeShield3", "DecorativeShield4",
"DecorativeShield5", "DecorativeShield6", "DecorativeShield7", "DecorativeShield8",
"DecorativeShield9", "DecorativeShield10", "DecorativeShield11", "DecorativeShieldSword1North",
"DecorativeShieldSword1West", "DecorativeShieldSword2North", "DecorativeShieldSword2West",
"DecorativeBowWest", "DecorativeBowNorth", "DecorativeAxeNorth", "DecorativeAxeWest",
"DecorativeSwordNorth", "DecorativeSwordWest", "DecorativeDAxeNorth", "DecorativeDAxeWest",
"LargePainting", "WomanPortrait1", "WomanPortrait2", "ManPortrait1", "ManPortrait2", "LadyPortrait1",
"LadyPortrait2", "Tapestry1N", "Tapestry2N", "Tapestry2W", "Tapestry3N", "Tapestry3W", "Tapestry4N",
"Tapestry4W", "Tapestry5N", "Tapestry5W", "Tapestry6N", "Tapestry6W"
]
},
{
"category": "Items.Construction.Decoration.Shields",
"types": [
"DecorativeShield1", "DecorativeShield2", "DecorativeShield3", "DecorativeShield4",
"DecorativeShield5", "DecorativeShield6", "DecorativeShield7", "DecorativeShield8",
"DecorativeShield9", "DecorativeShield10", "DecorativeShield11", "DecorativeShieldSword1North",
"DecorativeShieldSword1West", "DecorativeShieldSword2North", "DecorativeShieldSword2West"
]
},
{
"category": "Items.Construction.Decoration.Weapons",
"types": [
"DecorativeBowWest", "DecorativeBowNorth", "DecorativeAxeNorth", "DecorativeAxeWest",
"DecorativeSwordNorth", "DecorativeSwordWest", "DecorativeDAxeNorth", "DecorativeDAxeWest"
]
},
{
"category": "Items.Construction.Decoration.Paintings & Portraits",
"types": [
"LargePainting", "WomanPortrait1", "WomanPortrait2", "ManPortrait1", "ManPortrait2", "LadyPortrait1",
"LadyPortrait2"
]
},
{
"category": "Items.Construction.Decoration.Tapestries",
"types": [
"Tapestry1N", "Tapestry2N", "Tapestry2W", "Tapestry3N", "Tapestry3W", "Tapestry4N", "Tapestry4W",
"Tapestry5N", "Tapestry5W", "Tapestry6N", "Tapestry6W"
]
},
{
"category": "Items.Construction.Broken",
"types": [
"RuinedFallenChairA", "RuinedArmoire", "RuinedBookcase", "RuinedBooks", "CoveredChair",
"RuinedFallenChairB", "RuinedChair", "RuinedClock", "RuinedDrawers", "RuinedPainting", "WoodDebris"
]
},
{
"category": "Items.Construction.Rares",
"types": ["Rope", "IronWire", "SilverWire", "GoldWire", "CopperWire", "Whip", "PaintsAndBrush"]
},
{ "category": "Items.Construction.Doors", "types": ["BaseDoor"] },
{ "category": "Items.Construction.Floors", "types": ["BaseFloor"] },
{ "category": "Items.Construction.Containers", "types": ["Container"] },
{
"category": "Items.Construction.Furniture",
"types": [
"WoodenBench", "FancyWoodenChairCushion", "WoodenChairCushion", "WoodenChair", "BambooChair",
"Stool", "FootStool", "Throne", "WoodenThrone", "LargeTable", "Nightstand", "YewWoodTable",
"WritingTable", "Easel", "TallMusicStand", "ShortMusicStand"
]
},
{
"category": "Items.Construction.Furniture.Chairs",
"types": [
"WoodenBench", "FancyWoodenChairCushion", "WoodenChairCushion", "WoodenChair", "BambooChair",
"Stool", "FootStool", "Throne", "WoodenThrone"
]
},
{
"category": "Items.Construction.Furniture.Tables",
"types": ["LargeTable", "Nightstand", "YewWoodTable", "WritingTable"]
},
{
"category": "Items.Construction.Furniture.Other",
"types": ["Easel", "TallMusicStand", "ShortMusicStand"]
},
{ "category": "Items.Lights", "types": ["BaseLight"] },
{ "category": "Items.Food & Drink", "types": ["Food", "CookableFood", "BaseBeverage", "Glass"] },
{ "category": "Items.Food & Drink.Ready to eat", "types": ["Food"] },
{ "category": "Items.Food & Drink.Needs cooking", "types": ["CookableFood"] },
{ "category": "Items.Food & Drink.Beverages", "types": ["BaseBeverage", "Glass"] },
{ "category": "Items.Cartography", "types": ["MapItem"] },
{
"category": "Items.Stonecraft",
"types": ["Vase", "LargeVase", "StatueSouth", "StatueNorth", "StatueEast", "StatuePegasus", "StoneChair"]
},
{
"category": "Items.Glassblowing",
"types": [
"SmallFlask", "MediumFlask", "LargeFlask", "CurvedFlask", "LongFlask", "SpinningHourglass",
"GreenBottle", "RedBottle", "SmallBrownBottle", "SmallVioletBottle", "TinyYellowBottle",
"SmallBlueFlask", "SmallYellowFlask", "SmallRedFlask", "SmallEmptyFlask", "YellowBeaker",
"RedBeaker", "BlueBeaker", "GreenBeaker", "EmptyCurvedFlaskW", "RedCurvedFlask", "LtBlueCurvedFlask",
"EmptyCurvedFlaskE", "BlueCurvedFlask", "GreenCurvedFlask", "RedRibbedFlask", "VioletRibbedFlask",
"EmptyRibbedFlask", "LargeYellowFlask", "LargeVioletFlask", "LargeEmptyFlask", "AniRedRibbedFlask",
"AniLargeVioletFlask", "AniSmallBlueFlask", "SmallBlueBottle", "SmallGreenBottle", "EmptyVIalsWRack",
"FullVialsWRack", "EmptyJar", "FullJar", "HalfEmptyJar", "VioletStemmedBottle", "EmptyJars3",
"EmptyJars4", "FullJars3", "FullJars4", "EmptyJars2", "FullJars2", "HalfEmptyJars2", "EmptyVial",
"HourglassAni", "Hourglass", "TinyRedBottle", "SmallGreenBottle2", "Glass"
]
},
{
"category": "Items.Pots & Plants",
"types": [
"SmallEmptyPot", "LargeEmptyPot", "PottedCactus", "PottedCactus1", "PottedCactus2", "PottedCactus3",
"PottedCactus4", "PottedCactus5", "PottedPlant", "PottedPlant1", "PottedPlant2", "PottedTree",
"PottedTree1"
]
},
{
"category": "Items.Components",
"types": [
"BarrelLid", "BarrelStaves", "BarrelHoops", "BarrelTap", "Gears", "Springs", "Hinge", "Axle",
"AxleGears", "SextantParts", "ClockParts", "ClockFrame", "Clock", "ClockRight", "ClockLeft"
]
},
{ "category": "Items.Tools", "types": ["BaseTool", "BaseHarvestTool"] },
{ "category": "Items.Tools.Crafting", "types": ["BaseTool"] },
{ "category": "Items.Tools.Harvesting", "types": ["BaseHarvestTool"] },
{ "category": "Items.Traps", "types": ["BaseTrap"] },
{
"category": "Items.Gems",
"types": [
"Amber", "Amethyst", "Citrine", "Diamond", "Emerald", "Ruby", "Sapphire", "StarSapphire",
"Tourmaline"
]
},
{ "category": "Items.Boats", "types": ["BaseBoat", "BaseBoatDeed"] },
{ "category": "Items.Boats.Constructed", "types": ["BaseBoat"] },
{ "category": "Items.Boats.Deeds", "types": ["BaseBoatDeed"] },
{ "category": "Items.House Deeds", "types": ["HouseDeed", "HousePlacementTool"] },
{ "category": "Items.Camps", "types": ["BaseCamp"] },
{
"category": "Items.Magical",
"types": ["Spellbook", "SpellScroll", "BlankScroll", "BasePotion", "EtherealMount"]
},
{ "category": "Items.Magical.Scrolls", "types": ["SpellScroll", "BlankScroll"] },
{
"category": "Items.Magical.Scrolls.Necromancy",
"types": [
"AnimateDeadScroll", "BloodOathScroll", "CorpseSkinScroll", "CurseWeaponScroll", "EvilOmenScroll",
"HorrificBeastScroll", "LichFormScroll", "MindRotScroll", "PainSpikeScroll", "PoisonStrikeScroll",
"StrangleScroll", "SummonFamiliarScroll", "VampiricEmbraceScroll", "VengefulSpiritScroll",
"WitherScroll", "WraithFormScroll"
]
},
{ "category": "Items.Magical.Scrolls.Standard", "types": ["SpellScroll"] },
{
"category": "Items.Magical.Scrolls.Standard.Circle #1",
"types": [
"ClumsyScroll", "CreateFoodScroll", "FeeblemindScroll", "HealScroll", "MagicArrowScroll",
"NightSightScroll", "ReactiveArmorScroll", "WeakenScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #2",
"types": [
"AgilityScroll", "CunningScroll", "CureScroll", "HarmScroll", "MagicTrapScroll", "MagicUnTrapScroll",
"ProtectionScroll", "StrengthScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #3",
"types": [
"BlessScroll", "FireballScroll", "MagicLockScroll", "PoisonScroll", "TelekinesisScroll",
"TeleportScroll", "UnlockScroll", "WallOfStoneScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #4",
"types": [
"ArchCureScroll", "ArchProtectionScroll", "CurseScroll", "FireFieldScroll", "GreaterHealScroll",
"LightningScroll", "ManaDrainScroll", "RecallScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #5",
"types": [
"BladeSpiritsScroll", "DispelFieldScroll", "IncognitoScroll", "MagicReflectScroll",
"MindBlastScroll", "ParalyzeScroll", "PoisonFieldScroll", "SummonCreatureScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #6",
"types": [
"DispelScroll", "EnergyBoltScroll", "ExplosionScroll", "InvisibilityScroll", "MarkScroll",
"MassCurseScroll", "ParalyzeFieldScroll", "RevealScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #7",
"types": [
"ChainLightningScroll", "EnergyFieldScroll", "FlamestrikeScroll", "GateTravelScroll",
"ManaVampireScroll", "MassDispelScroll", "MeteorSwarmScroll", "PolymorphScroll"
]
},
{
"category": "Items.Magical.Scrolls.Standard.Circle #8",
"types": [
"EarthquakeScroll", "EnergyVortexScroll", "ResurrectionScroll", "SummonAirElementalScroll",
"SummonDaemonScroll", "SummonEarthElementalScroll", "SummonFireElementalScroll",
"SummonWaterElementalScroll"
]
},
{ "category": "Items.Magical.Potions", "types": ["BasePotion"] },
{ "category": "Items.Magical.Potions.Agility", "types": ["BaseAgilityPotion"] },
{ "category": "Items.Magical.Potions.Cure", "types": ["BaseCurePotion"] },
{ "category": "Items.Magical.Potions.Explosion", "types": ["BaseExplosionPotion"] },
{ "category": "Items.Magical.Potions.Heal", "types": ["BaseHealPotion"] },
{ "category": "Items.Magical.Potions.Poison", "types": ["BasePoisonPotion"] },
{ "category": "Items.Magical.Potions.Refresh", "types": ["BaseRefreshPotion"] },
{ "category": "Items.Magical.Potions.Strength", "types": ["BaseStrengthPotion"] },
{ "category": "Items.Magical.Ethereal Mounts", "types": ["EtherealMount"] },
{ "category": "Items.Uncategorized", "types": ["Item"] }
]

View file

@ -1,197 +0,0 @@
[
{ "category": "Mobiles", "types": ["Mobile"] },
{ "category": "Mobiles.Healers", "types": ["BaseHealer"] },
{
"category": "Mobiles.Champions",
"types": ["BaseChampion", "Harrower", "Silvani", "HarrowerTentacles"]
},
{ "category": "Mobiles.Guards", "types": ["BaseGuard", "BaseShieldGuard"] },
{ "category": "Mobiles.Escortables", "types": ["BaseEscortable"] },
{ "category": "Mobiles.Vendors", "types": ["BaseVendor"] },
{ "category": "Mobiles.Vendors.Guildmasters", "types": ["BaseGuildmaster"] },
{
"category": "Mobiles.Dummies",
"types": [
"DummyMace", "DummyFence", "DummySword", "DummyNox", "DummyStun", "DummySuper", "DummyHealer",
"DummyAssassin", "DummyTheif"
]
},
{ "category": "Mobiles.Creatures", "types": ["BaseCreature"] },
{
"category": "Mobiles.Creatures.Animals",
"types": [
"Gorilla", "Walrus", "Alligator", "Llama", "PackLlama", "PackHorse", "BullFrog", "GiantToad", "Hind",
"GreatHart", "DireWolf", "GreyWolf", "TimberWolf", "WhiteWolf", "HellHound", "Dog", "GrizzlyBear",
"PolarBear", "BlackBear", "BrownBear", "Bull", "Cow", "Bird", "Eagle", "Chicken", "Boar", "Pig",
"Rabbit", "JackRabbit", "Rat", "SewerRat", "GiantRat", "Goat", "MountainGoat", "Sheep", "Panther",
"PredatorHellCat", "HellCat", "SnowLeopard", "Cougar", "Cat", "BaseMount"
]
},
{ "category": "Mobiles.Creatures.Animals.Mounts", "types": ["BaseMount"] },
{ "category": "Mobiles.Creatures.Animals.Mounts.War Horses", "types": ["BaseWarHorse"] },
{ "category": "Mobiles.Creatures.Animals.Birds & Fowl", "types": ["Bird", "Eagle", "Chicken"] },
{ "category": "Mobiles.Creatures.Animals.Bovines", "types": ["Bull", "Cow"] },
{
"category": "Mobiles.Creatures.Animals.Bruins",
"types": ["GrizzlyBear", "PolarBear", "BlackBear", "BrownBear"]
},
{
"category": "Mobiles.Creatures.Animals.Canines",
"types": ["DireWolf", "GreyWolf", "TimberWolf", "WhiteWolf", "HellHound", "Dog"]
},
{ "category": "Mobiles.Creatures.Animals.Deer", "types": ["Hind", "GreatHart"] },
{
"category": "Mobiles.Creatures.Animals.Felines",
"types": ["Panther", "PredatorHellCat", "HellCat", "SnowLeopard", "Cougar", "Cat"]
},
{ "category": "Mobiles.Creatures.Animals.Frogs & Toads", "types": ["BullFrog", "GiantToad"] },
{ "category": "Mobiles.Creatures.Animals.Lizards", "types": ["Alligator"] },
{
"category": "Mobiles.Creatures.Animals.Llamas & Pack Animals",
"types": ["Llama", "PackLlama", "PackHorse"]
},
{
"category": "Mobiles.Creatures.Animals.Rodents",
"types": ["Rabbit", "JackRabbit", "Rat", "SewerRat", "GiantRat"]
},
{ "category": "Mobiles.Creatures.Animals.Porcines", "types": ["Boar", "Pig"] },
{ "category": "Mobiles.Creatures.Animals.Ruminants", "types": ["Goat", "MountainGoat", "Sheep"] },
{ "category": "Mobiles.Creatures.Animals.Uncategorized", "types": ["Gorilla", "Walrus"] },
{
"category": "Mobiles.Creatures.Ants",
"types": [
"RedSolenWorker", "RedSolenWarrior", "RedSolenQueen", "RedSolenInfiltratorQueen",
"RedSolenInfiltratorWarrior", "BlackSolenWorker", "BlackSolenWarrior", "BlackSolenQueen",
"BlackSolenInfiltratorQueen", "BlackSolenInfiltratorWarrior"
]
},
{
"category": "Mobiles.Creatures.Ants.Red",
"types": [
"RedSolenWorker", "RedSolenWarrior", "RedSolenQueen", "RedSolenInfiltratorQueen",
"RedSolenInfiltratorWarrior"
]
},
{
"category": "Mobiles.Creatures.Ants.Black",
"types": [
"BlackSolenWorker", "BlackSolenWarrior", "BlackSolenQueen", "BlackSolenInfiltratorQueen",
"BlackSolenInfiltratorWarrior"
]
},
{
"category": "Mobiles.Creatures.Elementals",
"types": [
"DullCopperElemental", "ShadowIronElemental", "CopperElemental", "BronzeElemental",
"GoldenElemental", "AgapiteElemental", "VeriteElemental", "ValoriteElemental", "AirElemental",
"BloodElemental", "FireElemental", "IceElemental", "WaterElemental", "PoisonElemental",
"ToxicElemental", "EarthElemental", "SnowElemental"
]
},
{
"category": "Mobiles.Creatures.Elementals.Ore Elementals",
"types": [
"DullCopperElemental", "ShadowIronElemental", "CopperElemental", "BronzeElemental",
"GoldenElemental", "AgapiteElemental", "VeriteElemental", "ValoriteElemental"
]
},
{ "category": "Mobiles.Creatures.Marine", "types": ["Dolphin", "SeaSerpent", "DeepSeaSerpent"] },
{ "category": "Mobiles.Creatures.Good", "types": ["Pixie", "Wisp", "EtherealWarrior", "Centaur"] },
{ "category": "Mobiles.Creatures.Evil", "types": ["BaseCreature"] },
{
"category": "Mobiles.Creatures.Evil.Age of Shadows",
"types": [
"FleshGolem", "Gibberling", "GoreFiend", "Ravager", "SkitteringHopper", "Treefellow", "VampireBat",
"WailingBanshee", "AbysmalHorror", "BoneDemon", "CrystalElemental", "DarknightCreeper",
"DemonKnight", "Devourer", "FleshRenderer", "Impaler", "MoundOfMaggots", "PatchworkSkeleton",
"ShadowKnight", "WandererOfTheVoid", "ChaosDaemon", "HordeMinion"
]
},
{ "category": "Mobiles.Creatures.Evil.Daemons", "types": ["IceFiend", "Balron", "Daemon"] },
{
"category": "Mobiles.Creatures.Evil.Dragons & Wyrms",
"types": [
"Dragon", "WhiteWyrm", "SerpentineDragon", "AncientWyrm", "ShadowWyrm", "SkeletalDragon", "Drake",
"Wyvern"
]
},
{
"category": "Mobiles.Creatures.Evil.Gargoyles",
"types": ["Gargoyle", "FireGargoyle", "StoneGargoyle"]
},
{ "category": "Mobiles.Creatures.Evil.Harpies", "types": ["Harpy", "StoneHarpy"] },
{
"category": "Mobiles.Creatures.Evil.Humans",
"types": [
"EvilMage", "EvilMageLord", "Betrayer", "Brigand", "Executioner", "Guardian", "KhaldunSummoner",
"KhaldunZealot"
]
},
{ "category": "Mobiles.Creatures.Evil.Lizards", "types": ["LavaLizard", "Lizardman"] },
{
"category": "Mobiles.Creatures.Evil.Mongbats, Imps, & Headless Ones",
"types": ["Mongbat", "StrongMongbat", "Imp", "HeadlessOne"]
},
{
"category": "Mobiles.Creatures.Evil.Ogres, Ettins, Trolls, Cyclopses, & Titans",
"types": ["Titan", "Cyclops", "Ettin", "FrostTroll", "Ogre", "Troll", "ArcticOgreLord", "OgreLord"]
},
{
"category": "Mobiles.Creatures.Evil.Ophidians",
"types": ["OphidianMage", "OphidianArchmage", "OphidianMatriarch", "OphidianWarrior", "OphidianKnight"]
},
{
"category": "Mobiles.Creatures.Evil.Orcs",
"types": ["OrcishMage", "Orc", "OrcishLord", "OrcBomber", "OrcCaptain", "OrcishLord", "OrcBrute"]
},
{
"category": "Mobiles.Creatures.Evil.Plague Beasts, Bog Things, & Slimes",
"types": ["Jwilson", "FrostOoze", "Slime", "PlagueSpawn", "PlagueBeast", "BogThing", "Bogling"]
},
{
"category": "Mobiles.Creatures.Evil.Plants",
"types": ["Corpser", "Quagmire", "WhippingVine", "SwampTentacle", "Reaper"]
},
{ "category": "Mobiles.Creatures.Evil.Ratmen", "types": ["Ratman", "RatmanArcher", "RatmanMage"] },
{
"category": "Mobiles.Creatures.Evil.Serpents",
"types": ["IceSerpent", "IceSnake", "LavaSerpent", "LavaSnake", "GiantSerpent", "SilverSerpent", "Snake"]
},
{
"category": "Mobiles.Creatures.Evil.Spiders",
"types": ["DreadSpider", "FrostSpider", "GiantSpider"]
},
{
"category": "Mobiles.Creatures.Evil.Terathans",
"types": ["TerathanMatriarch", "TerathanAvenger", "TerathanDrone", "TerathanWarrior"]
},
{
"category": "Mobiles.Creatures.Evil.Undead",
"types": [
"AncientLich", "Bogle", "BoneMagi", "Lich", "LichLord", "Shade", "SkeletalMage", "Spectre", "Wraith",
"BoneKnight", "SkeletalKnight", "Ghoul", "RottingCorpse", "Skeleton", "Zombie", "Mummy"
]
},
{
"category": "Mobiles.Creatures.Evil.Undead.Ghosts",
"types": ["Bogle", "Shade", "Spectre", "Wraith", "Ghoul"]
},
{
"category": "Mobiles.Creatures.Evil.Undead.Skeletons",
"types": ["BoneMagi", "SkeletalMage", "BoneKnight", "SkeletalKnight", "Skeleton"]
},
{
"category": "Mobiles.Creatures.Evil.Undead.Walking Dead",
"types": ["RottingCorpse", "Zombie", "Mummy"]
},
{
"category": "Mobiles.Creatures.Evil.Undead.Liches",
"types": ["AncientLich", "Lich", "LichLord"]
},
{
"category": "Mobiles.Creatures.Evil.Vortexes & Blade Spirits",
"types": ["EnergyVortex", "SandVortex", "BladeSpirits"]
},
{ "category": "Mobiles.Creatures.Evil.Uncategorized", "types": ["BaseCreature"] },
{ "category": "Mobiles.Uncategorized", "types": ["Mobile"] }
]

File diff suppressed because it is too large Load diff

View file

@ -261,8 +261,12 @@ namespace Server
{ {
for (var j = 0; j < alias.Aliases.Length; j++) for (var j = 0; j < alias.Aliases.Length; j++)
{ {
addToRefs(i, alias.Aliases[j], nameMap); var fullName = alias.Aliases[j];
addToRefs(i, alias.Aliases[j], nameMapInsensitive); var name = fullName.Substring(fullName.LastIndexOf('.') + 1);
addToRefs(i, fullName, nameMap);
addToRefs(i, fullName.ToLower(), nameMapInsensitive);
addToRefs(i, name, nameMap);
addToRefs(i, name.ToLower(), nameMapInsensitive);
} }
} }
} }

View file

@ -28,6 +28,13 @@ namespace Server.Json
throw new JsonException("The JSON value could not be converted to System.Type"); throw new JsonException("The JSON value could not be converted to System.Type");
} }
var typeName = reader.GetString();
var type = AssemblyHandler.FindTypeByName(typeName);
if (type == null)
{
Console.WriteLine("Invalid type {0} deserialized", typeName);
}
return AssemblyHandler.FindTypeByName(reader.GetString()); return AssemblyHandler.FindTypeByName(reader.GetString());
} }

View file

@ -950,7 +950,7 @@ namespace Server
if (m_Combatant == null) if (m_Combatant == null)
{ {
m_NetState?.SendChangeCombatant(Serial.Zero); m_NetState.SendChangeCombatant(Serial.Zero);
m_ExpireCombatant?.Stop(); m_ExpireCombatant?.Stop();
m_CombatTimer?.Stop(); m_CombatTimer?.Stop();
@ -959,7 +959,7 @@ namespace Server
} }
else else
{ {
m_NetState?.SendChangeCombatant(m_Combatant.Serial); m_NetState.SendChangeCombatant(m_Combatant.Serial);
m_ExpireCombatant ??= Timer.DelayCall(ExpireCombatantDelay, ExpireCombatant); m_ExpireCombatant ??= Timer.DelayCall(ExpireCombatantDelay, ExpireCombatant);
m_ExpireCombatant.Start(); m_ExpireCombatant.Start();
@ -968,8 +968,8 @@ namespace Server
if (CanBeHarmful(m_Combatant, false)) if (CanBeHarmful(m_Combatant, false))
{ {
DoHarmful(m_Combatant); DoHarmful(m_Combatant); // due to reflection, might make m_Combatant null
m_Combatant.PlaySound(m_Combatant.GetAngerSound()); m_Combatant?.PlaySound(m_Combatant.GetAngerSound());
} }
} }
@ -8618,12 +8618,7 @@ namespace Server
} }
} }
public virtual void DoHarmful(Mobile target) public virtual void DoHarmful(Mobile target, bool indirect = false)
{
DoHarmful(target, false);
}
public virtual void DoHarmful(Mobile target, bool indirect)
{ {
if (target == null || Deleted) if (target == null || Deleted)
{ {

View file

@ -17,7 +17,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Server.Items;
using Server.Json; using Server.Json;
using Server.Utilities;
namespace Server.Commands namespace Server.Commands
{ {
@ -26,7 +28,7 @@ namespace Server.Commands
public static CAGCategory Load() public static CAGCategory Load()
{ {
var root = new CAGCategory("Add Menu"); var root = new CAGCategory("Add Menu");
var path = Path.Combine(Core.BaseDirectory, "Data/objects.json"); var path = Path.Combine(Core.BaseDirectory, "Data/categorization.json");
var list = JsonConfig.Deserialize<List<CAGJson>>(path); var list = JsonConfig.Deserialize<List<CAGJson>>(path);
@ -76,9 +78,61 @@ namespace Server.Commands
parent.Nodes = new CAGNode[cag.Objects.Length]; parent.Nodes = new CAGNode[cag.Objects.Length];
for (var i = 0; i < cag.Objects.Length; i++) for (var i = 0; i < cag.Objects.Length; i++)
{ {
var obj = cag.Objects[i]; var cagObj = cag.Objects[i];
obj.Parent = parent; cagObj.Parent = parent;
parent.Nodes[i] = obj; parent.Nodes[i] = cagObj;
// Set ItemID and Hue
if (cagObj.Hue == null || cagObj.ItemID == null)
{
var type = cagObj.Type;
if (type.IsAssignableTo(typeof(Item)))
{
var item = cagObj.Type.CreateInstance<Item>();
if (cagObj.ItemID == null)
{
var itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
{
itemID = addon.Components[0].ItemID;
}
if (itemID > TileData.MaxItemValue)
{
itemID = 1;
}
cagObj.ItemID = itemID;
}
if (cagObj.Hue == null)
{
int hue = item.Hue & 0x7FFF;
hue = (hue & 0x4000) != 0 ? 0 : hue;
cagObj.Hue = hue == 0 ? null : hue;
}
item.Delete();
}
if (type.IsAssignableTo(typeof(Mobile)))
{
var m = cagObj.Type.CreateInstance<Mobile>();
cagObj.ItemID ??= ShrinkTable.Lookup(m, 1);
if (cagObj.Hue == null)
{
int hue = m.Hue & 0x7FFF;
hue = (hue & 0x4000) != 0 ? 0 : hue;
cagObj.Hue = hue == 0 ? null : hue;
}
m.Delete();
}
}
} }
} }
@ -86,10 +140,12 @@ namespace Server.Commands
} }
} }
public class CAGJson public record CAGJson
{ {
[JsonPropertyName("category")] public string Category { get; set; } [JsonPropertyName("category")]
public string Category { get; init; }
[JsonPropertyName("objects")] public CAGObject[] Objects { get; set; } [JsonPropertyName("objects")]
public CAGObject[] Objects { get; init; }
} }
} }

View file

@ -21,12 +21,15 @@ namespace Server.Commands
{ {
public class CAGObject : CAGNode public class CAGObject : CAGNode
{ {
[JsonPropertyName("type")] public Type Type { get; set; } [JsonPropertyName("type")]
public Type Type { get; set; }
[JsonPropertyName("gfx")] public int ItemID { get; set; }
#nullable enable #nullable enable
[JsonPropertyName("hue")] public int? Hue { get; set; } [JsonPropertyName("gfx")]
public int? ItemID { get; set; }
[JsonPropertyName("hue")]
public int? Hue { get; set; }
#nullable disable #nullable disable
public CAGCategory Parent { get; set; } public CAGCategory Parent { get; set; }

View file

@ -1,433 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Server.Items;
using Server.Json;
using Server.Utilities;
namespace Server.Commands
{
public static class Categorization
{
private static CategoryEntry m_RootItems, m_RootMobiles;
private static readonly Type typeofItem = typeof(Item);
private static readonly Type typeofMobile = typeof(Mobile);
private static readonly Type typeofConstructible = typeof(ConstructibleAttribute);
public static CategoryEntry Items
{
get
{
if (m_RootItems == null)
{
Load();
}
return m_RootItems;
}
}
public static CategoryEntry Mobiles
{
get
{
if (m_RootMobiles == null)
{
Load();
}
return m_RootMobiles;
}
}
public static void Initialize()
{
CommandSystem.Register("RebuildCategorization", AccessLevel.Administrator, RebuildCategorization_OnCommand);
}
[Usage("RebuildCategorization"), Description("Rebuilds the categorization data file used by the Add command.")]
public static void RebuildCategorization_OnCommand(CommandEventArgs e)
{
var root = new CategoryEntry(null, "Add Menu", new[] { Items, Mobiles });
var ceList = new List<CategoryEntry>();
ceList.AddRange(root.SubCategories);
Export(ceList, "Data/objects.json");
e.Mobile.SendMessage("Categorization menu rebuilt.");
}
public static void Export(List<CategoryEntry> ceList, string fileName)
{
var list = new List<CAGJson>();
foreach (var ce in ceList)
{
RecurseExport(list, ce, null);
}
JsonConfig.Serialize(fileName, list);
}
#nullable enable
public static void RecurseExport(List<CAGJson> list, CategoryEntry ce, string? category)
{
category = string.IsNullOrWhiteSpace(category) ? ce.Title : $"{category}{ce.Title}";
if (ce.Matched.Count > 0)
{
var objects = new CAGObject[ce.Matched.Count];
for (var i = 0; i < ce.Matched.Count; i++)
{
var cte = ce.Matched[i];
if (cte.Object is Item item)
{
var itemID = item.ItemID;
if (item is BaseAddon addon && addon.Components.Count == 1)
{
itemID = addon.Components[0].ItemID;
}
if (itemID > TileData.MaxItemValue)
{
itemID = 1;
}
int? hue = item.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
{
hue = 0;
}
objects[i] = new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
if (cte.Object is Mobile m)
{
var itemID = ShrinkTable.Lookup(m, 1);
int? hue = m.Hue & 0x7FFF;
if ((hue & 0x4000) != 0)
{
hue = 0;
}
objects[i] = new CAGObject
{
Type = cte.Type,
ItemID = itemID,
Hue = hue == 0 ? null : hue
};
}
throw new InvalidCastException(
$"Categorization Type Entry: {cte.Type.Name} is not a valid type."
);
}
list.Add(
new CAGJson
{
Category = category,
Objects = objects
}
);
}
var subCats = new List<CategoryEntry>(ce.SubCategories);
subCats.Sort(new CategorySorter());
for (var i = 0; i < subCats.Count; i++)
{
var subCat = subCats[i];
RecurseExport(list, subCat, category);
}
}
#nullable disable
public static void Load()
{
var types = new List<Type>();
AddTypes(Core.Assembly, types);
for (var i = 0; i < AssemblyHandler.Assemblies.Length; ++i)
{
AddTypes(AssemblyHandler.Assemblies[i], types);
}
m_RootItems = Load(types, "Data/items.cfg");
m_RootMobiles = Load(types, "Data/mobiles.cfg");
}
private static CategoryEntry Load(List<Type> types, string config)
{
var lines = CategoryLine.Load(config);
if (lines.Length <= 0)
{
return new CategoryEntry();
}
var index = 0;
var root = new CategoryEntry(null, lines, ref index);
Fill(root, types);
return root;
}
private static bool IsConstructible(Type type)
{
if (!type.IsSubclassOf(typeofItem) && !type.IsSubclassOf(typeofMobile))
{
return false;
}
var ctor = type.GetConstructor(Type.EmptyTypes);
return ctor?.IsDefined(typeofConstructible, false) == true;
}
private static void AddTypes(Assembly asm, List<Type> types)
{
var allTypes = asm.GetTypes();
for (var i = 0; i < allTypes.Length; ++i)
{
var type = allTypes[i];
if (type.IsAbstract)
{
continue;
}
if (IsConstructible(type))
{
types.Add(type);
}
}
}
private static void Fill(CategoryEntry root, List<Type> list)
{
for (var i = 0; i < list.Count; ++i)
{
var type = list[i];
var match = GetDeepestMatch(root, type);
if (match == null)
{
continue;
}
try
{
match.Matched.Add(new CategoryTypeEntry(type));
}
catch
{
// ignored
}
}
}
private static CategoryEntry GetDeepestMatch(CategoryEntry root, Type type)
{
if (!root.IsMatch(type))
{
return null;
}
for (var i = 0; i < root.SubCategories.Length; ++i)
{
var check = GetDeepestMatch(root.SubCategories[i], type);
if (check != null)
{
return check;
}
}
return root;
}
}
public class CategorySorter : IComparer<CategoryEntry>
{
public int Compare(CategoryEntry x, CategoryEntry y) =>
string.CompareOrdinal(x?.Title, y?.Title);
}
public class CategoryTypeSorter : IComparer<CategoryTypeEntry>
{
public int Compare(CategoryTypeEntry x, CategoryTypeEntry y) =>
string.CompareOrdinal(x?.Type.Name, y?.Type.Name);
}
public class CategoryTypeEntry
{
public CategoryTypeEntry(Type type)
{
Type = type;
Object = type.CreateInstance<object>();
}
public Type Type { get; }
public object Object { get; }
}
public class CategoryEntry
{
public CategoryEntry(CategoryEntry parent = null, string title = "(empty)", CategoryEntry[] subCats = null)
{
Parent = parent;
Title = title;
SubCategories = subCats ?? Array.Empty<CategoryEntry>();
Matches = Array.Empty<Type>();
Matched = new List<CategoryTypeEntry>();
}
public CategoryEntry(CategoryEntry parent, CategoryLine[] lines, ref int index)
{
Parent = parent;
var text = lines[index].Text;
var start = text.IndexOfOrdinal('(');
if (start < 0)
{
throw new FormatException($"Input string not correctly formatted ('{text}')");
}
Title = text.Substring(0, start).Trim();
var end = text.IndexOf(')', ++start);
if (end < start)
{
throw new FormatException($"Input string not correctly formatted ('{text}')");
}
text = text.Substring(start, end - start);
var split = text.Split(';');
var list = new List<Type>();
for (var i = 0; i < split.Length; ++i)
{
var type = AssemblyHandler.FindTypeByName(split[i].Trim());
if (type == null)
{
Console.WriteLine("Match type not found ('{0}')", split[i].Trim());
}
else
{
list.Add(type);
}
}
Matches = list.ToArray();
list.Clear();
var ourIndentation = lines[index].Indentation;
++index;
var entryList = new List<CategoryEntry>();
while (index < lines.Length && lines[index].Indentation > ourIndentation)
{
entryList.Add(new CategoryEntry(this, lines, ref index));
}
SubCategories = entryList.ToArray();
entryList.Clear();
Matched = new List<CategoryTypeEntry>();
}
public string Title { get; }
public Type[] Matches { get; }
public CategoryEntry Parent { get; }
public CategoryEntry[] SubCategories { get; }
public List<CategoryTypeEntry> Matched { get; }
public bool IsMatch(Type type)
{
var isMatch = false;
for (var i = 0; !isMatch && i < Matches.Length; ++i)
{
isMatch = type == Matches[i] || type.IsSubclassOf(Matches[i]);
}
return isMatch;
}
}
public class CategoryLine
{
public CategoryLine(string input)
{
int index;
for (index = 0; index < input.Length; ++index)
{
if (char.IsLetter(input, index))
{
break;
}
}
if (index >= input.Length)
{
throw new FormatException($"Input string not correctly formatted ('{input}')");
}
Indentation = index;
Text = input.Substring(index);
}
public int Indentation { get; }
public string Text { get; }
public static CategoryLine[] Load(string path)
{
var list = new List<CategoryLine>();
if (File.Exists(path))
{
using var ip = new StreamReader(path);
string line;
while ((line = ip.ReadLine()) != null)
{
list.Add(new CategoryLine(line));
}
}
return list.ToArray();
}
}
}

View file

@ -218,7 +218,11 @@ namespace Server.Gumps
if (node is CAGObject obj) if (node is CAGObject obj)
{ {
var itemID = obj.ItemID; var itemID = obj.ItemID ?? 0;
if (itemID == 0)
{
Console.WriteLine("Type {0} does not have a valid item id or shrink table entry.", obj.Type);
}
var bounds = ItemBounds.Table[itemID]; var bounds = ItemBounds.Table[itemID];

View file

@ -253,8 +253,6 @@ namespace Server.Gumps
{ {
AddHtml(10, 125, 400, 20, Color(Center("Generating"), LabelColor32)); AddHtml(10, 125, 400, 20, Color(Center("Generating"), LabelColor32));
AddButtonLabeled(220, 150, GetButtonID(3, 107), "Rebuild Categorization");
AddButtonLabeled(20, 175, GetButtonID(3, 101), "Teleporters"); AddButtonLabeled(20, 175, GetButtonID(3, 101), "Teleporters");
AddButtonLabeled(220, 175, GetButtonID(3, 102), "Moongates"); AddButtonLabeled(220, 175, GetButtonID(3, 102), "Moongates");
@ -2127,10 +2125,6 @@ namespace Server.Gumps
InvokeCommand("Decorate"); InvokeCommand("Decorate");
notice = "Decoration has been generated."; notice = "Decoration has been generated.";
break; break;
case 107:
InvokeCommand("RebuildCategorization");
notice = "Categorization menu has been regenerated. The server should be restarted.";
break;
case 110: case 110:
InvokeCommand("Freeze"); InvokeCommand("Freeze");

View file

@ -1,6 +1,8 @@
namespace Server.Items namespace Server.Items
{ {
[Furniture, Flippable(0xF65, 0xF67, 0xF69)] [Furniture]
[Flippable(0xF65, 0xF67, 0xF69)]
[TypeAlias("Server.Items.Easle")]
public class Easel : Item public class Easel : Item
{ {
[Constructible] [Constructible]

View file

@ -1,5 +1,6 @@
namespace Server.Items namespace Server.Items
{ {
[TypeAlias("Server.Items.TelekinisisScroll")]
public class TelekinesisScroll : SpellScroll public class TelekinesisScroll : SpellScroll
{ {
[Constructible] [Constructible]

View file

@ -19,7 +19,7 @@ namespace Server
public static int Lookup(int body, int defaultValue) public static int Lookup(int body, int defaultValue)
{ {
m_Table ??= Load(); m_Table ??= Load();
var index = body < m_Table.Length ? m_Table[body] : -1; var index = body >= 0 && body < m_Table.Length ? m_Table[body] : -1;
if (index < 0) if (index < 0)
{ {
return defaultValue; return defaultValue;
@ -35,10 +35,12 @@ namespace Server
if (!File.Exists(path)) if (!File.Exists(path))
{ {
Console.WriteLine("No table found!");
return Array.Empty<int>(); return Array.Empty<int>();
} }
var table = new List<int>(); var list = new List<(int, int)>();
var length = 0;
using var ip = new StreamReader(path); using var ip = new StreamReader(path);
string line; string line;
@ -61,10 +63,14 @@ namespace Server
var body = Utility.ToInt32(split[0]); var body = Utility.ToInt32(split[0]);
var item = Utility.ToInt32(split[1]); var item = Utility.ToInt32(split[1]);
if (body >= 0) if (body < 0)
{ {
table[body] = item; continue;
} }
list.Add((body, item));
length = Math.Max(body + 1, length);
} }
} }
catch catch
@ -73,7 +79,13 @@ namespace Server
} }
} }
return table.ToArray(); var table = new int[length];
foreach (var (body, item) in list)
{
table[body] = item;
}
return table;
} }
} }
} }

View file

@ -2567,7 +2567,7 @@ namespace Server.Mobiles
} }
} }
public override void DoHarmful(Mobile target, bool indirect) public override void DoHarmful(Mobile target, bool indirect = false)
{ {
base.DoHarmful(target, indirect); base.DoHarmful(target, indirect);