Ive been using tutorials and such to learn scripting. Im still quite new at it.
I have encountered an issue I have not been able to overcome with my fledgling scripting skills.
In NWN1 there existed a function GetNumberPartyMembers. This function does not exist in NWN2 and I have tried using all kinds of complex Get variations to count the # of players in a group. Not necessarily limited to 'players', but characters. i.e... Player + 3 other characters in player's group.
What I am trying to script is a way to set an integer that is equal to the number of characters in the player's group that I can then use elsewhere in the script. Basicly, the player takes his group of 1-4 into a dungeon. I want certain triggers to then spawn an equal amount of pre-set NPCs. If the player goes in solo, these triggers will respond to the integer gSize (meaning 'group Size') and the Boss spawns solo. If the player goes in with 2 editor added characters (making a group of 3), then the Boss spawns with two friends. 3 versus 3.
I just can not figure out a way to get that 'gSize' integer. So I am here seeking the instruction of those in the 'know'.
Party size count?
Débuté par
Khanquer
, sept. 13 2011 08:06
#1
Posté 13 septembre 2011 - 08:06
#2
Posté 13 septembre 2011 - 12:00
Here's a snip from one of my scripts that does just this, set up for use in a single-player module:
// Get the number of party members for further calculations
object oMasterPC = GetFirstPC(TRUE);
int nParty;
object oMember = GetFirstFactionMember(oMasterPC);
while (GetIsObjectValid(oMember))
{
nParty ++;
oMember = GetNextFactionMember(oMasterPC);
}
// Get the number of party members for further calculations
object oMasterPC = GetFirstPC(TRUE);
int nParty;
object oMember = GetFirstFactionMember(oMasterPC);
while (GetIsObjectValid(oMember))
{
nParty ++;
oMember = GetNextFactionMember(oMasterPC);
}
#3
Posté 13 septembre 2011 - 02:07
This will set up an interesting situation in which the more companions a player has, the more XP they will receive, since the XP is not split up between the players but is awarded equally. I guess if this is just for a single encounter, it really will not make a very big difference. If it is repeated often throughout the game, balancing things coul become challenging.
#4
Posté 13 septembre 2011 - 04:42
Sweet, thanks! I will get that put in later today and try it out.
Thank you for taking the time.
Thank you for taking the time.
#5
Posté 13 septembre 2011 - 06:39
I'd suggest looking at the community script library. It's got documentation above each function, and is far better organized than the libraries that come with the game, and ready to be used in projects both small and large. ( i include in the zip ALL of my scripts, these are for multiple projects and can be ignored or reviewed as you see fit )
Quite a few functions, like the party count, actually come with the game, but there is no rhyme or reason as to where you find them, and quite a few are done so poorly it will cause problems, i have functions in files organized by category so you know all the math functions are in the math include, and things like the party count are in the player include.
You can use the includes as is, all you need is the "CSLLibrary" folder, and just the particular includes you happen to be using.
This would make your projects more compatible with other projects using the same library, and it also will help you avoid numerous gotcha moments ( there are serious errors in core includes which cause the toolset to just crash with no explanation, which are very hard to trace down ). I've spent weeks at a time troubleshooting scripts and finally ended up learning that including ANY include from the game as is, is just asking for problems since you end up including hundreds of files, and i've rewritten most of the functions used in game.
Of course the biggest advantage is quite a few functions which every project needs are already done and tested.
You can also just use it to find out how to do things, search thru the functions, see how it's done and read the doxygen comments, and most of all notice things you aren't thinking of yet. It is by design set up to be used at your own pace, either lightly or fully.
Note that in my version of the function, it checks proximity and area as well, to ensure players have to be near each other. I would think that this is something you should look at for your own function, ( that is using my position library to check ).
Quite a few functions, like the party count, actually come with the game, but there is no rhyme or reason as to where you find them, and quite a few are done so poorly it will cause problems, i have functions in files organized by category so you know all the math functions are in the math include, and things like the party count are in the player include.
You can use the includes as is, all you need is the "CSLLibrary" folder, and just the particular includes you happen to be using.
This would make your projects more compatible with other projects using the same library, and it also will help you avoid numerous gotcha moments ( there are serious errors in core includes which cause the toolset to just crash with no explanation, which are very hard to trace down ). I've spent weeks at a time troubleshooting scripts and finally ended up learning that including ANY include from the game as is, is just asking for problems since you end up including hundreds of files, and i've rewritten most of the functions used in game.
Of course the biggest advantage is quite a few functions which every project needs are already done and tested.
You can also just use it to find out how to do things, search thru the functions, see how it's done and read the doxygen comments, and most of all notice things you aren't thinking of yet. It is by design set up to be used at your own pace, either lightly or fully.
Note that in my version of the function, it checks proximity and area as well, to ensure players have to be near each other. I would think that this is something you should look at for your own function, ( that is using my position library to check ).
int CSLCountParty(object oPC, int nDist = 0)
{
object oParty = GetFirstFactionMember(oPC);
int nCnt = 0;
while (GetIsObjectValid(oParty))
{
if ( CSLPCIsClose(oPC, oParty, nDist))
{
nCnt++;
}
oParty = GetNextFactionMember(oPC);
}
return nCnt;
}
Modifié par painofdungeoneternal, 13 septembre 2011 - 06:44 .
#6
Posté 13 septembre 2011 - 07:38
I just extensively tested your script _Knightmare_ with a small addition and I could not get it to work at all.
// Get the number of party members for further calculations
object oMasterPC = GetFirstPC(TRUE);
int nParty;
object oMember = GetNextFactionMember(oMasterPC);
while (GetIsObjectValid(oMember))
{
nParty++;
oMember = GetNextFactionMember(oMasterPC);
}
// Inform player how many characters are in group.
string gSize;
gSize = IntToString(nParty) + " is how many characters are presently in your party.";
FloatingTextStringOnCreature(gSize, oMasterPC);
It just keeps returning a value of 0 on the character in game. I tried it on groups of sizes 1-4 and tried it using each of the 2-4 additional characters. If I use the main PC, the text appears with a 0 one time, but if I use any of the other 2-4 toons, it actually says it twice in the chat box for reasons I can not even begin to fathom. All I can figure from this is that is getting an incorrect count of players in the player's group.
I will delve into painofdungeoneternal's stuffs if it is not to overwhelming for my fledgling scripting skills at this time. Im really just trying to overcome small challenges and learn scripting without overwhelming myself, but this lack of a GetNumberPartyMembers function in NWN2 is daunting. Any more suggestions would be appreciated.
// Get the number of party members for further calculations
object oMasterPC = GetFirstPC(TRUE);
int nParty;
object oMember = GetNextFactionMember(oMasterPC);
while (GetIsObjectValid(oMember))
{
nParty++;
oMember = GetNextFactionMember(oMasterPC);
}
// Inform player how many characters are in group.
string gSize;
gSize = IntToString(nParty) + " is how many characters are presently in your party.";
FloatingTextStringOnCreature(gSize, oMasterPC);
It just keeps returning a value of 0 on the character in game. I tried it on groups of sizes 1-4 and tried it using each of the 2-4 additional characters. If I use the main PC, the text appears with a 0 one time, but if I use any of the other 2-4 toons, it actually says it twice in the chat box for reasons I can not even begin to fathom. All I can figure from this is that is getting an incorrect count of players in the player's group.
I will delve into painofdungeoneternal's stuffs if it is not to overwhelming for my fledgling scripting skills at this time. Im really just trying to overcome small challenges and learn scripting without overwhelming myself, but this lack of a GetNumberPartyMembers function in NWN2 is daunting. Any more suggestions would be appreciated.
#7
Posté 13 septembre 2011 - 07:53
painofdungeoneternal,
Im looking over the link you sent, Im quite overwhelmed thus far. So Im backing out some.
Basicly, I am trying to learn scripting and I give myself small projects to do in a simple module, not with any set module to release goals in mind, just scripts to develop so I can futher learn and maybe one day actually script.
I see you may have misunderstood me a little, but not much. I am trying to make a 'counter' for 1 players group, not multiple players at this point.
I have two linked areas. Using a lever in Area1 tells the player how many characters are in their group (this is to verify my counter is working). Then the player uses a 2nd leverl in Area1 that transports them to Area2 and using a switch spawns an equal number of enemies to how many characters in the one players group.
i.e... Player wants to solo, so the lever says "1 is how many characters are presently in your party." Player then goes to Area2 and 1 enemy spawns.
Player wants to go into Area2 with 3 characters, lever says "3 is how many characters are presently in your party." Player then goes to Area2 and 3 enemys spawn.
Im not having a problem with the transition to Area2 and getting enemies to spawn, the problem is getting some kind of 'group size' counter. Nothing I seem to come up with works.
Im looking over the link you sent, Im quite overwhelmed thus far. So Im backing out some.
Basicly, I am trying to learn scripting and I give myself small projects to do in a simple module, not with any set module to release goals in mind, just scripts to develop so I can futher learn and maybe one day actually script.
I see you may have misunderstood me a little, but not much. I am trying to make a 'counter' for 1 players group, not multiple players at this point.
I have two linked areas. Using a lever in Area1 tells the player how many characters are in their group (this is to verify my counter is working). Then the player uses a 2nd leverl in Area1 that transports them to Area2 and using a switch spawns an equal number of enemies to how many characters in the one players group.
i.e... Player wants to solo, so the lever says "1 is how many characters are presently in your party." Player then goes to Area2 and 1 enemy spawns.
Player wants to go into Area2 with 3 characters, lever says "3 is how many characters are presently in your party." Player then goes to Area2 and 3 enemys spawn.
Im not having a problem with the transition to Area2 and getting enemies to spawn, the problem is getting some kind of 'group size' counter. Nothing I seem to come up with works.
#8
Posté 13 septembre 2011 - 08:20
_Knightmare_ wrote...
object oMember = GetFirstFactionMember(oMasterPC);
Khanquer wrote...
object oMember = GetNextFactionMember(oMasterPC);
ps. Pain's stuff is pretty heady, but it's the direction to go w/ Scripting.
#9
Posté 13 septembre 2011 - 08:32
Thanks for pointing that out Kevl.
Still doesn't work.
// Get the number of party members for further calculations
object oMasterPC = GetFirstPC(TRUE);
int nParty;
object oMember = GetFirstFactionMember(oMasterPC);
while (GetIsObjectValid(oMember))
{
nParty++;
oMember = GetNextFactionMember(oMasterPC);
}
// Inform player how many characters are in group.
string gSize;
gSize = IntToString(nParty) + " is how many characters are presently in your party.";
FloatingTextStringOnCreature(gSize, oMasterPC);
I see Pain's suggestion is a function. I have yet to learn to write those actually. I just want something in the script itself that gives me an just an accurate integer count of the # of players in the group. Seems simple, but has, in practive, proved daunting to this nub.
// Get the number of party members for further calculations
object oMasterPC = GetFirstPC(TRUE);
int nParty;
object oMember = GetFirstFactionMember(oMasterPC);
while (GetIsObjectValid(oMember))
{
nParty++;
oMember = GetNextFactionMember(oMasterPC);
}
// Inform player how many characters are in group.
string gSize;
gSize = IntToString(nParty) + " is how many characters are presently in your party.";
FloatingTextStringOnCreature(gSize, oMasterPC);
I see Pain's suggestion is a function. I have yet to learn to write those actually. I just want something in the script itself that gives me an just an accurate integer count of the # of players in the group. Seems simple, but has, in practive, proved daunting to this nub.
Modifié par Khanquer, 13 septembre 2011 - 08:35 .
#10
Posté 13 septembre 2011 - 08:34
My thought is you can look at examples of what has been done, and thus learn how to script based on well done scripts. Quite a bit can be learned this way, and i'd suggest not learning "how" to do things based on reading the scripts that come with the game, and instead look at folks like kaedrin, 0100010, and learn based on their examples. That example should bring up some issues you "might" not of thought of, as most of the functions are a bit battle tested. Really don't want you spinning your wheels reinventing things, or worse blindly going in a direction that turns out to be a dead end.
What you want is GetFirstFactionMember, GetNextFactionMember used together ( you use first initially and then use next )
http://www.nwnlexico...tionmember.html
It works the same in NWN1 and NWN2 99% of the time.
The parameter defaults to TRUE, so put the parameter as FALSE and i think it will get all of the henchmen as well as the PC's ( pretty sure the lexicon is wrong on it only doing non-pc's ).
GetFirstPC should NOT ever be used unless you just want to iterate all the players in a game, and you only will have one. You are using the WRONG function, and your scripts will seem to work fine in single player, but you are using a function which is not designed for what you are using it for. You should review Referencing Objects in Scripts and use the correct function for the type of script you are running.
Then you would pass the above oPC or oLever to any functions you use.
or
Or even ( i updated that function to have the option of a FALSE parameter in my next version of the CSL )
The function could be included from a separate file, and thus would basically mean you just need to code 2 lines, and it would be easier for you to maintain.
What you want is GetFirstFactionMember, GetNextFactionMember used together ( you use first initially and then use next )
http://www.nwnlexico...tionmember.html
It works the same in NWN1 and NWN2 99% of the time.
The parameter defaults to TRUE, so put the parameter as FALSE and i think it will get all of the henchmen as well as the PC's ( pretty sure the lexicon is wrong on it only doing non-pc's ).
GetFirstPC should NOT ever be used unless you just want to iterate all the players in a game, and you only will have one. You are using the WRONG function, and your scripts will seem to work fine in single player, but you are using a function which is not designed for what you are using it for. You should review Referencing Objects in Scripts and use the correct function for the type of script you are running.
object oPC = GetLastUsedBy(); object oLever = OBJECT_SELF;
Then you would pass the above oPC or oLever to any functions you use.
or
void main()
{
object oMasterPC = GetLastUsedBy();
int nParty;
object oMember = GetFirstFactionMember(oMasterPC, FALSE);
while (GetIsObjectValid(oMember))
{
nParty++;
oMember = GetNextFactionMember(oMasterPC,FALSE);
}
// Inform player how many characters are in group.
FloatingTextStringOnCreature( IntToString(nParty) + " is how many characters are presently in your party.", oMasterPC);
}
Or even ( i updated that function to have the option of a FALSE parameter in my next version of the CSL )
/**
* Counts the Number of Players in the Party that are in the same area as the PC with optional Max Distance to PC
* @author
* @param oPC The players whose faction to count
* @param nDist Distance in meters, note this is a integer for legacy code reasons. If distance of -1 is entered it ignores distance and counts all those in the current module/server
* @param bPCOnly True will only count actual players, if False will count NPC's, Henchmen, Familiars
* @see
* @return Count of members in oPC's faction
*/
int CSLCountParty(object oPC, int nDist = 0, int bPCOnly=TRUE)
{
object oParty = GetFirstFactionMember(oPC, bPCOnly );
int nCnt = 0;
while (GetIsObjectValid(oParty))
{
if ( nDist==-1 || CSLPCIsClose(oPC, oParty, nDist))
{
nCnt++;
}
oParty = GetNextFactionMember(oPC, bPCOnly );
}
return nCnt;
}
void main()
{
object oMasterPC = GetLastUsedBy();
int nParty = CSLCountParty(oMasterPC, -1, FALSE);
// Inform player how many characters are in group.
FloatingTextStringOnCreature( IntToString(nParty) + " is how many characters are presently in your party.", oMasterPC);
}
The function could be included from a separate file, and thus would basically mean you just need to code 2 lines, and it would be easier for you to maintain.
Modifié par painofdungeoneternal, 13 septembre 2011 - 08:50 .
#11
Posté 13 septembre 2011 - 08:41
Sweeeeeeeeeeeeet! Thanks Pain!
It works now, just had to change that GetFirstPC to GetFirstFactionMember.
The counter seems to be working now.
It works now, just had to change that GetFirstPC to GetFirstFactionMember.
The counter seems to be working now.
#12
Posté 14 septembre 2011 - 12:55
Oops sorry, I clipped that out of a much larger script.
#13
Posté 14 septembre 2011 - 01:01
Fix the getfirstpc() in there for one thing in that larger script, sure there is a better way to implement that.





Retour en haut






