Jump to content

NVSE plugin -- What do we need?


prideslayer

Recommended Posts

Posted

 

Are Args a stack? Meaning do you have to re-iteratively call ExtractArgs until it returns false?

 

 

No... not as far as I've seen anyway. I based that bit on this function:

 

bool Cmd_ListReplaceNthForm_Execute(COMMAND_ARGS)
{
UInt32* refResult = (UInt32*)result;
*refResult = 0;

BGSListForm* pListForm = NULL;
TESForm* pReplaceWith = NULL;
UInt32 n = eListEnd;

if (ExtractArgsEx(EXTRACT_ARGS_EX, &pListForm, &pReplaceWith, &n)) {
	if (pListForm && pReplaceWith) {
		TESForm* pReplaced = pListForm->ReplaceNthForm(n, pReplaceWith);
		if (pReplaced) {
			*refResult = pReplaced->refID;
		}
	}
}

return true;
}

 

 

Both are defined nearly identically as well. The NVSE function above is defined in Commands_List.h like this:

 

static ParamInfo kParams_ReplaceNthForm[3] = 
{
{	"form list",	kParamType_FormList,	0		},
{	"replaceWith",	kParamType_AnyForm,		0		},
{	"formIndex",	kParamType_Integer,		1		}
};

DEFINE_CMD_ALT(ListReplaceNthForm, ListReplaceNth, replaces the nth form of the list with the specified form, 0, 3, kParams_ReplaceNthForm); 

 

And mine is thus:

static ParamInfo kParams_NX_IsInList[3] = 
{
{	"formlist", kParamType_FormList, 0 },
{	"form",     kParamType_AnyForm, 0  },
{	"recurse",  kParamType_Integer, 1  }
};

DEFINE_COMMAND_PLUGIN(NX_IsInList, "Returns 1 if the item is in the list", 0, 3, kParams_NX_IsInList);

 

DEFINE_COMMAND and the rest are just macros.. I don't see any errors in mine compared to theirs..

 

#define DEFINE_CMD_ALT(name, altName, description, refRequired, numParams, paramInfo) \
DEFINE_CMD_FULL(name, altName, description, refRequired, numParams, paramInfo, Cmd_Default_Parse)	

#define DEFINE_COMMAND(name, description, refRequired, numParams, paramInfo) \
DEFINE_CMD_FULL(name, , description, refRequired, numParams, paramInfo, Cmd_Default_Parse)	

#define DEFINE_COMMAND_PLUGIN(name, description, refRequired, numParams, paramInfo) \
DEFINE_CMD_FULL(name, , description, refRequired, numParams, paramInfo, NULL)

 

 

Posted

In the interest of full disclosure I've tried calling it with different param sets in my test ESP and always get the same result. Switching ExtractArgs to ExtractArgsEx is also the same; supposedly the EX version does some magic to get around the type checking that the the vanilla version (which is a blind call into the game engine) does. I changed my init of n from 0 to eListEnd as the example uses, thinking maybe it's used for something else initially, but that also made no difference -- it just comes back unmodified.

 

If you're feeling charitable astymma, I can attach the project source + the esp, but I know this is the last thing you want to get sucked in to. May have to just bother Ian again in another PM asking him if there's anything special I need to know about ExtractArgs.

Posted

Works perfectly as expected with integers...

 

bool Cmd_NX_TestMultiParams_Execute(COMMAND_ARGS)
{
 UInt32 x = 0;
 UInt32 y = 0;
 UInt32 z = 0;
 bool         eares      = false;

 _MESSAGE("START TMP");
 eares = ExtractArgs(EXTRACT_ARGS, &x, &y, &z);
 if (eares)
 {
   _MESSAGE("SUCCESS");
   _MESSAGE(" RES %i %i %i", x, y, z);
 }
 else
 {
   _MESSAGE("FAIL");
 }
 _MESSAGE("END TMP");

 return true;
}

 

Defined:

static ParamInfo kParams_NX_TestMultiParams[3] = 
{
{ "int x", kParamType_Integer, 0 },
{ "int y", kParamType_Integer, 0 },
{ "int z", kParamType_Integer, 0 }
};

DEFINE_COMMAND_PLUGIN(NX_TestMultiParams, "Returns sum of three integers", 0, 3, kParams_NX_TestMultiParams);

 

Posted

Testing to see if that pointer to pointer crap is wrong now.. maybe the function I copied doesn't work either.

 

Heh no all that did was crash the game.. argh.. hulk waking up! ;)

 

edit: in retrospect.. duh.. it can't change the pointer address if I don't give it a pointer to a pointer.

Posted

In the interest of full disclosure I've tried calling it with different param sets in my test ESP and always get the same result. Switching ExtractArgs to ExtractArgsEx is also the same; supposedly the EX version does some magic to get around the type checking that the the vanilla version (which is a blind call into the game engine) does. I changed my init of n from 0 to eListEnd as the example uses' date=' thinking maybe it's used for something else initially, but that also made no difference -- it just comes back unmodified.

 

If you're feeling charitable astymma, I can attach the project source + the esp, but I know this is the last thing you want to get sucked in to. May have to just bother Ian again in another PM asking him if there's anything special I need to know about ExtractArgs.

[/quote']

Well, I don't mind looking at the source but I'll give you my email address in a PM instead.

 

Posted

Sent. I don't mind sharing it here either. It's a small file when I clean up the intellisense files and precompiled headers.

 

Maybe you'll see something obvious that I've missed.

Posted

(obviously does not return the sum.. but you know. Something may be wrong with what I'm passing in from the ESP somehow.. argh

 

 

 

TBH, that should NEVER fail as each integer will hold the 32bit pointer which is an integer. I didn't see anywhere where those functions were typecasting unless argument type forces a typecast. Though I'm guessing that it's just using sizeof on your parameter and extracting Args into the sizes of each argument pointer you pass in. I doubt an integer would ever fail, no matter what 32 bits you grab.

 

Gonna take a look at your source and the nvse source and see if I can't nail down a descriptive usage of ExtractArgs and ExtractArgsEx. They're obviously chunk extraction functions but how much data massaging do they do?

Posted

Gonna take a look at your source and the nvse source and see if I can't nail down a descriptive usage of ExtractArgs and ExtractArgsEx. They're obviously chunk extraction functions but how much data massaging do they do?

 

ExtractArgs is built in to the engine, it's an external call to some place in the engine found through their investigation. If ExtractArgsEx is the same as ExtractArgsIX from OBSE, then it's just a function that does away with the typechecking the game engine does on ExtractArgs() by casting them all to the baseform first or something.

 

Also, FYI, this is also working fine:

 

.cpp

bool Cmd_NX_TestMultiParamsB_Execute(COMMAND_ARGS)
{
 TESForm* x     = NULL;
 TESForm* y     = NULL;
 TESForm* z     = NULL;
 bool     eares = false;

 _MESSAGE("START TMP");
 eares = ExtractArgs(EXTRACT_ARGS, &x, &y, &z);
 if (eares)
 {
   _MESSAGE("SUCCESS");
   _MESSAGE(" RES %x %x %x", x, y, z);
 }
 else
 {
   _MESSAGE("FAIL");
 }
 _MESSAGE("END TMP");

 return true;
}

 

.h

static ParamInfo kParams_NX_TestMultiParamsB[3] = 
{
{ "int x", kParamType_AnyForm, 0 },
{ "int y", kParamType_AnyForm, 0 },
{ "int z", kParamType_AnyForm, 0 }
};

DEFINE_COMMAND_PLUGIN(NX_TestMultiParamsB, "Get three forms", 0, 3, kParams_NX_TestMultiParamsB);

 

Moving on to test more thorougly with lists. *something* is going wrong.

Posted

I did.. what a fool. It's working fine.

 

I set the stage to 100 to skip all the previous stages because I was tired of waiting. I forgot in the first stage I was assigning the refs to begin with. This lead to a call to my function with a '0' ref, which apparently extract args does not like, as any args after that were also ignored.

 

Sorry to waste your time, but thanks for wasting it with me anyway.

 

article-1025141-05D736BD0000044D-634_233x590.jpg

allons-y!

Posted

I did.. what a fool. It's working fine.

 

I set the stage to 100 to skip all the previous stages because I was tired of waiting. I forgot in the first stage I was assigning the refs to begin with. This lead to a call to my function with a '0' ref' date=' which apparently extract args does not like, as any args after that were also ignored.

 

Sorry to waste your time, but thanks for wasting it with me anyway.

 

[img']http://i.dailymail.co.uk/i/pix/2008/06/09/article-1025141-05D736BD0000044D-634_233x590.jpg[/img]

allons-y!

 

Careful with that, might turn me into a Sonic Death Monkey and while I like "Let's Get It On", I don't sing well.

 

Posted

What I could really use at this point though, and have all but given up on figuring out, is how I can get the step debugger hooked up to this thing.

 

I switch FONV to run in a window so I can switch to the debugger and attach it, which "works fine." It picks up the dll, though it does put a little red mark on it saying that it isn't loaded where it should be (understandable given what NVSE is doing).

 

However, setting a breakpoint in it anywhere just causes FONV to crash and *not* dump me into the debugger as soon as the breakpoint is hit.

Posted

What I could really use at this point though' date=' and have all but given up on figuring out, is how I can get the step debugger hooked up to this thing.

 

I switch FONV to run in a window so I can switch to the debugger and attach it, which "works fine." It picks up the dll, though it does put a little red mark on it saying that it isn't loaded where it should be (understandable given what NVSE is doing).

 

However, setting a breakpoint in it anywhere just causes FONV to crash and *not* dump me into the debugger as soon as the breakpoint is hit.

[/quote']

 

Yeah that's a known issue and TBH I'm not that familiar with the MS IDE to be all that helpful. May have to, and I know this is the pit of hell, go look at the documentation lol.

Posted

I don't mind their documentation, MSDN is better thought out than most projects out there.. :) So far though, it hasn't been a help at all. I think it just doesn't like the way NVSE loads and then repositions the DLL. I might have to compile a debug version of NVSE and test by attaching to that instead.. then again, that still doesn't get nvse_loader out of the way.

 

Logging to the file with all those _MESSAGE macros will work for now. It cleans the file up every time the game or geck are started anyway.

Posted

It's only annoying because C/C++ lack so much of the RTTI (introspection and reflection) I've gotten used to in other languages. Can't even tell what class something is without modifying all the classes to support it.. talk about living in the stone age! ;)

Posted

It's only annoying because C/C++ lack so much of the RTTI (introspection and reflection) I've gotten used to in other languages. Can't even tell what class something is without modifying all the classes to support it.. talk about living in the stone age! ;)

 

That's more a factor of the class creator than c++ classes. Having RTTI is a simple matter of creating your class to support it. It's all a matter if inheritance' date=' methods and properties.[/url']

Posted

Oh, I "get it." My point is that the mechanism is in place in the base classes from which all objects descend, in more modern languages. You don't have to do anything as the developer in order to support "someobj->getClassName()" or "getClassName(someobj)" depending on the language implementation, even when someobj is declared as a base class itself or the equivalent of a void*.

 

For me to get that kind of functionality, I'd have to modify every class in NVSE to support it, which.. has obvious problems, unless the NVSE team would accept the diff. ;)

 

edit: typeid() may work, I thought that was a compile-time thing though, and not actually a runtime thing. I'll check it out.

Posted

OP updated, another one down!

 

(int) NX_IsInList list:formlist item:object (recurse:int) : >0 if the item in any form is contained within the formlist, 0 otherwise. Setting recurse to 1 will cause it to check formlists within the current formlist to near infinite depth (recurse not yet implemented).

 

Returns a value from 0 to 4.

0 : item not in list.

1 : item in list exactly.

2 : base form of item in list.

3 : item is a baseform of another item in list.

4 : base form of item is the same as base form of another item in list.

 

Take the following three vars:

set itemA to AcousticGuitar
set itemB to player.placeatme AcousticGuitar 1
set itemC to player.placeatme AcousticGuitar 1

 

And two formlists. List1 contains itemA, list2 contains itemB.

 

"NX_IsInList List1 itemA" and "NX_IsInList List2 itemB" will both return 1.

"NX_IsInList List1 itemB" will return 2.

"NX_IsInList List2 itemA" will return 3.

"NX_IsInList List2 itemC" will return 4.

 

Posted

Oh' date=' I "get it." My point is that the mechanism is in place in the base classes from which all objects descend, in more modern languages. You don't have to do anything as the developer in order to support "someobj->getClassName()" or "getClassName(someobj)" depending on the language implementation, even when someobj is declared as a base class itself or the equivalent of a void*.

 

For me to get that kind of functionality, I'd have to modify every class in NVSE to support it, which.. has obvious problems, unless the NVSE team would accept the diff. ;)

 

edit: typeid() may work, I thought that was a compile-time thing though, and not actually a runtime thing. I'll check it out.

[/quote']

That was my point, they probably should have included it in the first lpace... but it IS a hobby project for modding, so I doubt that getting it to work ever took a back seat to anything else hehe.

 

Posted

The only thing worse than not being able to understand what you 2 are going on about is being able to half understand it :)

 

Sounds like some good stuff coming anyways, just thought of another one to possibly add.

Some sort of time control for the MessageEx function or perhaps a MessageEx3 for 3 seconds, MessageEx5 for 5 seconds etc

 

Or maybe being able to call up the centre dialuge box with the OK bit to clear.

Might be a nightmare to implement and not worth the trouble, but just an idea.

Posted

I'll look into those Hal. Had to take a bit of a break.. was trying to get the changerace bit in (it'll be NPCs only -- player is 'fixed' to PlayerRace) before the initial beta -- which is going to need lots of testing and experimentation. :)

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...