DOL's support of user scripts has long provided a useful ability to create custom NPC classes with extended functionality (new methods) and create NPCs in-game based on custom classes.
The main value I see in a custom default NPC class is not the ability to extend the behavior (new methods), but to change the existing behavior (over-ridden methods). Am I looking at this from a narrow perspective, or is this a good assessment? Extended behavior = use custom classes that extend GameNPC; modified behavior = use a custom class as the default NPC class.
Ideally, I think a nice solution would be to run some reflection code at server startup that looks at all the methods in the custom NPC class and replaces the methods of DOL.GS.GameNPC with the overriden definitions. The custom class itself would then never be directly instantiated - all DOL.GS.GameNPC instances would have the modified code. Does anyone know how to do this, or even if it's possible? Sadly, I know very little about reflection.
In the absence of the above solution, I think we could expand our efforts to replace instances of GameNPC with instances of the CustomGameNPC. Mark has already covered the vast majority of cases by applying CustomGameNPC to all NPCs loaded from the database that have their class type set to "DOL.GS.GameNPC." I'm seeking to cover the other cases:
- Add a CreateDefaultNPC() method
- Replace code like "x = new GameNPC()" with "x = CreateDefaultNPC()"
Reflection is never invoked to create a DOL.GS.GameNPC, so the overhead in creating a normal GameNPC instance should be very low. I wonder if there is some way to cache the object type once we have initially obtained it via reflection to avoid repeated use of reflection to instantiate new objects?
Casting the object to GameNPC ensures that GameNPC methods are available to be called. User scripts know what code they're dealing with and what methods to expect, but core code also has to deal with custom NPCs, and we want to ensure that, at a minimum, all the regular GameNPC methods are available to be called.