Custom default NPC class

A place to submit .patch fixes for the DOL SVN

Moderator: Developer Team

Custom default NPC class

Postby Kakuri » Wed Sep 16, 2009 11:30 pm

Mark's addition of a server property for specifying the default NPC class is a very nice feature for customization. It does have some shortcomings, however...
  1. Any custom NPCs you have already created that extend GameNPC have to be updated to extend your custom class
  2. Scripts that create NPCs need to create NPCs of the custom class, rather than GameNPC
To ease script development, I think we could add a method to create a default (server props default) GameNPC like so:
Code: Select all
public static GameNPC CreateDefaultNPC()
{
string defaultClassType = ServerProperties.Properties.GAMENPC_DEFAULT_CLASSTYPE;

if( defaultClassType == "DOL.GS.GameNPC" )
{
return new GameNPC();
}

return CreateInstance( defaultClassType, typeof( GameNPC ) ) as GameNPC;
}
The CreateInstance method:
Code: Select all
public static Object CreateInstance( string className, Type baseClass )
{
Object instance = null;

Assembly gameServerAssembly = Assembly.GetAssembly( typeof( GameServer ) );

try
{
instance = gameServerAssembly.CreateInstance( className );
}
catch
{
instance = null;
}

if( instance == null )
{
foreach( Assembly scriptAssembly in ScriptMgr.Scripts )
{
try
{
instance = scriptAssembly.CreateInstance( className );
}
catch
{
instance = null;
}

if( instance != null )
{
break;
}
}
}

if( instance != null && baseClass != null )
{
try
{
instance = Convert.ChangeType( instance, baseClass );
}
catch
{
instance = null;
}
}

return instance;
}
What I'm wondering is where these methods should go... maybe CreateDefaultNPC should be a static method of GameNPC? The CreateInstance method could perhaps reduce some duplicated code - where should it go in the namespace? GameServer?
User avatar
Kakuri
Developer
 
Posts: 803
Joined: Tue Oct 28, 2008 10:40 pm
Website: http://enlight.hostrator.com/

Re: Custom default NPC class

Postby Tolakram » Wed Sep 16, 2009 11:36 pm

Not sure on this. Good points though, I never thought about those issues.
- Mark
User avatar
Tolakram
Storm / Storm-D2 Admin
 
Posts: 9189
Joined: Tue Jun 13, 2006 1:49 am
Location: Kentucky, USA

Re: Custom default NPC class

Postby Kakuri » Thu Sep 17, 2009 1:41 am

I'm thinking:
GameNPC.CreateDefaultNPC()
ScriptMgr.CreateInstance( string className, Type baseClass )

Sound good? Should I perhaps rename CreateInstance to CreateClassInstance (to reduce confusion with, say, instanced zones)?
User avatar
Kakuri
Developer
 
Posts: 803
Joined: Tue Oct 28, 2008 10:40 pm
Website: http://enlight.hostrator.com/

Re: Custom default NPC class

Postby Tolakram » Thu Sep 17, 2009 1:48 am

CreateObject?
- Mark
User avatar
Tolakram
Storm / Storm-D2 Admin
 
Posts: 9189
Joined: Tue Jun 13, 2006 1:49 am
Location: Kentucky, USA

Re: Custom default NPC class

Postby Graveen » Thu Sep 17, 2009 8:16 am

Ok. What we would like is a class replacement for GameNPC.

But it 'll be used at 95% for creating GameNPC. So we should handle quickly GameNPC (reflexion is slow, although i think - because we are instancing all GameNPC at startup (?) it should be ok - but to try)

Notice, i guess this is already done for GamePlayer, i suppose your changes are similar to the GamePlayer ones ?

My trouble is to see you are considering the returned class as GameNPC, this could be a trouble for accessing new methods. In the case theses methods are override, i suppose it works nicely.
Image
* pm me to contribute in Dawn of Light: code, database *
User avatar
Graveen
Project Leader
 
Posts: 12661
Joined: Fri Oct 19, 2007 9:22 pm
Location: France

Re: Custom default NPC class

Postby Kakuri » Thu Sep 17, 2009 2:21 pm

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:
  1. Add a CreateDefaultNPC() method
  2. 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.
User avatar
Kakuri
Developer
 
Posts: 803
Joined: Tue Oct 28, 2008 10:40 pm
Website: http://enlight.hostrator.com/

Re: Custom default NPC class

Postby Kakuri » Thu Sep 17, 2009 3:08 pm

Wow.
http://www.codeproject.com/KB/cs/LinFuPart1.aspx

Method call interception!!
User avatar
Kakuri
Developer
 
Posts: 803
Joined: Tue Oct 28, 2008 10:40 pm
Website: http://enlight.hostrator.com/

Re: Custom default NPC class

Postby Kakuri » Thu Sep 17, 2009 8:30 pm

Wow, I feel stupidly late to the party. I got pretty excited when I discovered reflection in Java years ago, but my job took me away from Java, so I never really got into it. More recently I've been learning Lisp, which is extremely exciting in the control and flexibility it gives you over your code, but is not widely used or supported, and it's a bear to learn... reminds me of assembly! :shock:

So today I'm wondering what possibilities C#'s reflection opens up, and I discovered LinFu, which it turns out is kind of old news. The author is currently working on LinFu's successor, Hiro. In researching LinFu, I find out that the field of code injection (or IoC: Inversion of Control) is fairly active and popular, with multiple IoC frameworks for C#. Then later in the day I noticed the announcement of the Noop language, which is backed by Google and includes code injection as part of the language design! Also discovered there are, of course, multiple IoC frameworks for Java.

Exciting stuff! Better that I learn about it late than never!

I'm beginning to see we may not need a custom GameNPC class at all if you can just inject your own code wherever you like.
User avatar
Kakuri
Developer
 
Posts: 803
Joined: Tue Oct 28, 2008 10:40 pm
Website: http://enlight.hostrator.com/

Re: Custom default NPC class

Postby Graveen » Thu Sep 17, 2009 8:46 pm

hey i never had really occasion to use reflexion, but i like it the little i use it :)
Image
* pm me to contribute in Dawn of Light: code, database *
User avatar
Graveen
Project Leader
 
Posts: 12661
Joined: Fri Oct 19, 2007 9:22 pm
Location: France


Return to “%s” DOL Code Contributions

Who is online

Users browsing this forum: No registered users and 1 guest