logo logo

 Back to main page

The NWNX Community Forum

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 
Get uLong from Creature?

 
Post new topic   Reply to topic    nwnx.org Forum Index -> Windows development
View previous topic :: View next topic  
Author Message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Mon Jul 26, 2010 23:41    Post subject: Get uLong from Creature? Reply with quote

Hey guys,
Since I am now able to build nwnx_funcs and stuff,
I thought I would give it a go, at adding my own PossessCreature function to it.

I've managed to get the Function Definitions into the classes etc fine, and it builds, however, Im not entirely sure about how to go about getting the necessary
uLong argument for the target creature.

What I have so far is this

Code:


//inside the CNWSCreature Class
void            (__thiscall *CNWSCreature__PossessCreature)(CNWSCreature *pTHIS,unsigned long) = (void (__thiscall *)(CNWSCreature* pTHIS, unsigned long))0x004CD1B0;



void CNWSCreature::PossessCreature(unsigned long uCreId) {
    CNWSCreature__PossessCreature(this,uCreId);
}





//Inside the Funcs Def
int CNWNXFuncs::PossessCreature() {

//Im guessing oObject is the creatue doing the Possession, and P1 has to
//be the Creature being possessed, HOWEVER....will it accept P1 as a
//CNWSCreature, or is there a way of getting it as a uLong. Or... Can
//I script in the nwnx_funcs include file to pass P1 as the Object ID of the
// creature, and then cast it as a uLong?  Suggestions?
   ((CNWSCreature*)oObject)->PossessCreature((CNWSCreature*)P1);

}

Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Tue Jul 27, 2010 0:36    Post subject: K, my problem is Reply with quote

I just dont know how to pass multiple objects into nwnx_funcs...


When calling the function, I am using a PlayerTool, which then sets the local string

Code:

void NWNXFuncs_PossessCreature(object oPC,object oTarget) {
        string sID = ObjectToString(oTarget);
        SetLocalString(oPC, "NWNX!FUNCS!POSSESSCREATURE", sID);
        DeleteLocalString(oPC, "NWNX!FUNCS!POSSESSCREATURE");

}


However, this doesnt work. Although it does reach nwnx_funcs, and appears in the logs, its the sID that is not right.
I cant find any examples to look at either, where the function is run by a Creature, targetting a Creature.

Eg - oObject is oPC in this (from nwnx_funcs point of view)
but I dont know how to get the target creature, into a uLong that the PossessCreature function will accept.

Note - On the other hand... I havent had any crashes, so thats good.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Tue Jul 27, 2010 1:07    Post subject: Reply with quote

Love talking to myself on here btw.... it truly rocks...
Note- Just using the below as reference, this is actually the function that comes before PossessCreature, if you are a DM using the DMPowers version. Just needed to see what type of arguments it passed to The PossessCreature
Code:

int __thiscall CNWSCreature__PossessCreatureDM(void *this, int a2, unsigned __int8 a3)
{
  int result; // eax@1
  void *v4; // edi@1
  int v5; // esi@1
  int v6; // edi@2

  v4 = this;
  CNWSCreature__PossessCreature(a2);
  result = CServerExoApp__GetCreatureByGameObjectID(a2);
  v5 = result;
  if ( result )
  {
    v6 = *((_DWORD *)v4 + 1);
    if ( *(_DWORD *)(result + 4) != v6 )
      *(_DWORD *)(result + 2864) = v6;
    CNWSCreature__SetAssociateType(a3);
    CNWSObject__ClearAllActions(v5);
    result = CNWSCreature__DMClearScripts(0);
  }
  return result;
}




Ok, from what I can tell from the Pseudocode, (right spelling?) dWord which would be the hex value of the object... I think...
Can be used to get the game object id via
Code:

CServerExoApp__GetCreatureByGameObjectID(a2);


and then I should be able to pass the result from this, into the PossessCreature function.....


Of course, if someone wants to jump in with the answer.... feel free to do so?
Back to top
View user's profile Send private message
MaxRock



Joined: 24 Jan 2008
Posts: 196

PostPosted: Tue Jul 27, 2010 2:42    Post subject: Reply with quote

Yes, most of the time that ulong is the id returned from ObjectToString; I think the official name is object id.

So for your first post you can pass the string from ObjectToString along and it should work just fine
Code:

...
unsigned int oID = 0;
sscanf(Parameters, "%08X", &oID);
((CNWSCreature*)gameObject)->PossessCreature(oID);
...

which should make the script work:
Code:

void NWNXFuncs_PossessCreature(object oPC,object oTarget) {
        string sID = ObjectToString(oTarget);
        SetLocalString(oPC, "NWNX!FUNCS!POSSESSCREATURE", sID);
        DeleteLocalString(oPC, "NWNX!FUNCS!POSSESSCREATURE");

}



This on the other hand:
Code:
CServerExoApp__GetCreatureByGameObjectID(a2);


Will give you a pointer (a CWNSCreature pointer to be exact) to the Creature with object id a2.
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Tue Jul 27, 2010 2:46    Post subject: Reply with quote

I will give that a go.

I had tried sscanf earlier, however, it was causing the plugin to crash.
But saying that, I didnt know what params to use with sscanf (the %08X)

Will give it a go, and report back shortly.

If it does work, perhaps you might wana include it in the nwnx_funcs
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Tue Jul 27, 2010 2:51    Post subject: Reply with quote

HOLY SUGAR CRAP ON A SWIZEL STICK


It worked.


Although, there is some additional coding to be done.
It made me possess the NPC,
but it showed all the NPC's associates as party members, and it gave me xp, which allowed me to attempt to do a level up. When I tried to do a levelup, it caused the server to crash - cant level up Possessed beings as they were players etc.

But its certainly progress.

My guess is, that to complete this, we would need to look at the function calls of the normal possess creature, and see what all it calls, in order to make it function correctly.
Eg - SetAssociates etc


Further problems arrise with
1. The Creature you possess continues to walk waypoints,
2. Dying inside your possessed body results in server crash.
3. Leveling up inside your possessed body results in server crash
4. Unable to unpossess. (No unpossess radial button - and the Playertool feats I used to do the possession, are not present either)


I've added this
Code:

   unsigned int oID = 0;
   sscanf(Params, "%08X", &oID);
   ((CNWSCreature*)oObject)->PossessCreature(oID);
   
   CNWSCreature *cre;
   cre = ((*NWN_AppManager)->app_server->srv_internal)->GetCreatureByGameObjectID(oID);
   cre->DMClearScripts(1);
   


Just on the off chance it will at least stop my possessed toon from obeying its AI.
Saying that.... there is likely an AI function hidden somewhere, to toggle it on and off.


Note
DMClearScripts(1) does clear the AI of possessed beings.
Step closer. Hehe


I believe the solution to the crashes lyes in the
Code:

CNWSCreature::SetAssociateType(ushort)

Function...

This is the only other function that the DM Possession function calls, that the Possession Function does not.
I think it possibly sets the Creature, to an associate type, that the game knows to handle as a Possessed Creature, and therefore, disable level ups, and maybe set the proper special abilities etc.
Unpossess etc

When ever I die as a possessed creature, it does not let me exit the body, or respawn, so my guess is, that the game doesnt know I have possessed the creature, because the AssociateType has not been set properly.

Only problem is, I have no clue what the uShort values of the associates types are.

I've learned that the DM Possession uses uShort Value of 8, and Normal Possession uses uShort of 7.
However, when setting these values, it resulted in occasional crashing.

Didnt give me the correct GUI though.
Back to top
View user's profile Send private message
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Tue Jul 27, 2010 19:30    Post subject: going to make an attempt Reply with quote

Im going to make an attempt, at getting possess Creature working, by going further up the function call line.

Eg
CNWSDungeonMaster::PossessCreature actually comes first in the PossessCreatureDM possession.

Its possible, if I go high up enough in the functions, I will find one which sets all the correct values etc, and makes a working possession.


Im unsure how to make my own classes in c++, is it sufficient that I make a class file, which just has the Function declaration inside it, or do I need to put details of the struct inside the class file.

It is my hope, I can cast the CNWSCreature (player) as a CNWSDungeonMaster to get them to call this function.

Didnt quite work...... Caused crashed....

CNWSCreature::PossessCreature does at least allow possession, it just happens to have a few bugs.

CNWSDungeonMaster::PossessCreature accepts the following arguments.
unsigned Long - Creature ID
unsigned short - Seems to be the same values for the Associate type, either 7 or 8.

But when I fed these in via the makeshift class I made, it crashed. Since it is getting the same arguments that a DM doing the same action would give, I am assuming it is possibly my implimentation of the class that caused the crashes.


It could just be a case of.... not being possible to get a fully working PossessCreature working via nwnx Sad
Back to top
View user's profile Send private message
MaxRock



Joined: 24 Jan 2008
Posts: 196

PostPosted: Tue Jul 27, 2010 21:32    Post subject: Reply with quote

Quote:
It is my hope, I can cast the CNWSCreature (player) as a CNWSDungeonMaster to get them to call this function.


I guess that would depend on the cast.
A simple CNWSDungeonMaster *DM = (CNWSDungeonMaster*)NWSCreature definitly won't work. Well, the "cast" works but you can't do anything with it, since all it does is set the a pointer to the beginning of the creature structure.
CNWSCreature is derived from CNWSObject; it's a CNWSObject with creature specific data appended.

The dungeon master class is derived from CNWSPlayer which is derived from CNWSClient, so their structures are very different.

It's not quite clear to me on how the whole process works either. All that PossessCreature seems to do is Transfer player control to another object and copy area data. But I haven't found anything that links back to the original creature...

What happens if you simply call CNWSCreature::Unposses?
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Baaleos



Joined: 02 Sep 2007
Posts: 830

PostPosted: Wed Jul 28, 2010 0:53    Post subject: didnt try Reply with quote

I didnt try Unpossess,
But I suspect it would likely have worked.

I was more concerned with trying to get a Possession working, that didnt end up crashing the server when things like barter, or level ups were attempted.

Also trying to find a way to get an Authentic Unpossess Button to appear.
One would think that nwn would detect that possession is ongoing, and as such, we need an unpossess button.


In anycase, I guess thats why I got a crash from the DungeonMaster class I tried to make, because I tried to base it on the CNWSCreature class.

Do you think you would be able to get the possession working to a good quality?

It would be a good addition to nwnx_funcs if it could be made stable.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    nwnx.org Forum Index -> Windows development All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group