Aller au contenu

Photo

count party size script issues


  • Veuillez vous connecter pour répondre
19 réponses à ce sujet

#1
slowdive.fan

slowdive.fan
  • Members
  • 235 messages
So I have been working on a script that should return the number of party members. The IWd campaign is designed to work with SP and MP and it uses the SoZ party creation GUI. So a party can consist of MP PCs, each of those PCs can have their own created player characters from the SoZ GUI, regular OC type companions (maybe someday but not at the moment), animal compaions, summons, familiars, and henchmen.

The script should only count MP PCs, SoZ party creation PCs, and OC type companions. I don't want to count animal companions, summons, henchmen, or familiars.

Here is my script which seems to be working fine if the currently controlled player is your first created character. It only counts one if the currently controlled character is one of your SoZ party creation GUI PCs.

int GetNumberOfCompanions()
{
// We alway use the SAME object for the GetFirst/Next faction
// member calls - always define it first. Here it is the first PC.

int nComp = 0;

object oPC = GetFirstPC(FALSE);
while(GetIsObjectValid(oPC) == TRUE)
{
if (GetIsOwnedByPlayer(oPC))
{
// Get the first PC party member
object oPartyMember = GetFirstFactionMember(oPC, FALSE);
// We stop when there are no more valid PC's in the party.
while(GetIsObjectValid(oPartyMember) == TRUE)
{
if ((GetIsPC(oPartyMember)) || (GetIsRosterMember(oPartyMember)))
{
// Do something to party member
nComp++;
SendMessageToPC(oPC, "Found a PC");
}
else
SendMessageToPC(oPC, "Found a non-PC");
// Get the next PC member of oPC's faction.
// If we put anything but oPC into this, it may be a totally
// unreliable loop!
oPartyMember = GetNextFactionMember(oPC, FALSE);
}
}
oPC = GetNextPC(FALSE);
}
string sComp = IntToString(nComp);
SendMessageToPC(oPC, "Number of Companions = " + sComp);

return nComp;
}

Any ideas? It seems easy until the SoZ party creation PCs get involved.

#2
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
I just have this in my codebase at present which just does actual players.
CSLGetNumberPartyMembers

Add in GetAssociateType to make it work as you intend ( and make the loop actually go thru all companions by changing it from TRUE to FALSE )


int ASSOCIATE_TYPE_NONE             = 0;
int ASSOCIATE_TYPE_HENCHMAN         = 1;
int ASSOCIATE_TYPE_ANIMALCOMPANION  = 2;
int ASSOCIATE_TYPE_FAMILIAR         = 3;
int ASSOCIATE_TYPE_SUMMONED         = 4;
int ASSOCIATE_TYPE_DOMINATED        = 5;

/** 
* Returns the associate type of the specified creature.
* @param oAssociate object to get the associate type of
* @return an ASSOCIATE_TYPE_* constant.
* @onerror Returns ASSOCIATE_TYPE_NONE if the creature is not the associate of anyone.
*/
int GetAssociateType( object oAssociate );

Changing the loop from TRUE ( True PC's only ), to FALSE, and then filtering by GetAssociateType() being less than 2, would do the trick i think...

/**
* Return the number of other players in the PC's party
* Does NOT include companions, familiars, summons or dominated.
*/
int CSLGetNumberPartyPCAndHenchmen(object oPC )
{
    int nNumber = 1;
    object oPartyMem = GetFirstFactionMember(oPC, FALSE);
    while (GetIsObjectValid(oPartyMem))
    {
		/*
		int ASSOCIATE_TYPE_NONE             = 0;
		int ASSOCIATE_TYPE_HENCHMAN         = 1;
		int ASSOCIATE_TYPE_ANIMALCOMPANION  = 2;
		int ASSOCIATE_TYPE_FAMILIAR         = 3;
		int ASSOCIATE_TYPE_SUMMONED         = 4;
		int ASSOCIATE_TYPE_DOMINATED        = 5;
		*/
		if ( GetAssociateType(oPartyMem) < 2 )
		{
        	nNumber++;
        }
        oPartyMem = GetNextFactionMember(oPC, FALSE);
    }
    return nNumber;
}

Seems like something which should be in the CSL library, so if you could test that, I'll put it in so others can use it as well.

Modifié par painofdungeoneternal, 01 mars 2012 - 05:42 .


#3
slowdive.fan

slowdive.fan
  • Members
  • 235 messages
That seems like it would work as long as the currently controlled character is your first created character. My problems have been occuring when my current controlled character is one of my SoZ party creation GUI created characters. It is almost like the engine thinks that my main PC has a party, but my other created PCs do not have their own party. So when the controlled PC is my first created character the loop detects all the party members, but when the controlled character is a SoZ GUI created character he had no party members so the script returns 1 member.

#4
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
Hmm i would try what i posted, the SOZ created and real players should be in the same faction. Have not tested it ( don't really do much official content to begin with ). Kaldor probably knows how this works better.

Yes you'd have to make sure the oPC fed into that is in the party faction, but there are functions which can help with that. Can there be more than one party in MP? You don't have to use the currently controlled character, and can instead use functions to get the owner of whatever creature you are dealing with ( or even getfirstPC but you really have to think it thru as there generally are better options )

Modifié par painofdungeoneternal, 01 mars 2012 - 06:58 .


#5
slowdive.fan

slowdive.fan
  • Members
  • 235 messages
Yeah, it is messy... I guess I'll need to go the old trial and error route...eats into my bug fixing time though ;-) I'm sure I'll figure it out eventually...thanks so much for your help pain.

#6
kevL

kevL
  • Members
  • 4 061 messages
this worked correctly in SoZ (1 PC, 3 SoZ chars, 2 companions, 2 summons, 1 familiar) whether I controlled the PC, an SoZ char, a companion, or the familiar.

int GetFactChars()
{
  int i = 0;

  object oPC = GetFirstPC(); // -> or grab a PC in the party
  object oFM = GetFirstFactionMember(oPC, FALSE);
  while (GetIsObjectValid(oFM))
  {
    if (!GetAssociateType(oFM)) i++;
    oFM = GetNextFactionMember(oPC, FALSE);
  }

  return i;
}

void main()
{
  int i = GetFactChars();
  SendMessageToPC(GetFirstPC(FALSE), "Test = " + IntToString(i));
}


i = 6

( get back ta bug fixin, sir, if this works for ya )

#7
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
Does he want henchmen included? I did less than 2 to include henchman but not any other types of associates ( not sure which ones are technically henchman ). The only difference beyond that that is it uses GetFirstPC() inside the function, where i am expecting that be passed in on the parameter ( if you have to use it of course ).

#8
kevL

kevL
  • Members
  • 4 061 messages
yah, SD said no henchmen

i was going over his script and when you posted constants i thought that's brilliant! so I started playing with it ...

#9
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
ah k, then mine would have to be just like yours with the !GetAssociateType(oFM) or perhaps something more easy on a novice would be GetAssociateType(oFM) == ASSOCIATE_TYPE_NONE

hmm need a generic function where you just pass in parameters to decide which are included.

#10
kevL

kevL
  • Members
  • 4 061 messages
something like,

int GetFacts(object oFM, int iAssocType1 = FALSE, int iAssocType2 = FALSE, int iAssocType3 = FALSE, ...)


?

edit, + int iPConly, gets complicated i'm sure

Modifié par kevL, 01 mars 2012 - 09:47 .


#11
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
Yes, something like that, and throw in regular summons or undead summons ( to support those rules enforcing number of hit dice of undead )

It would have to be simple on top, and branch out inside to optimize the code. PC only would just switch the faction loop to true. Something like the following.

CSLCountFactionMembersOfType(
object oMainFactionMember = OBJECT_INVALID
int bIncludePlayers
int bIncludeHenchmen
int bIncludeAnimalCompanions
int bIncludeFamiliars
int bIncludeSummons
int bIncludeDominated
int bOnlyUndeadSummons = FALSE
int bOnlyMagicalSummons = FALSE ( the non undead ones like animals and celestial tigers, etc )
int bOnlyInfernalSummons = FALSE
int bOnlyAngelicSummons = FALSE

if OBJECT_INVALID can just get the "main" pc using getfirstpc or nearest pc depending on if they are in multiplayer. Regardless have it do a GetMaster( oPC ) to get the main actor in charge, even though that might not be needed at all.

Not sure how to get if a creature is a SOZ companion ( which is now associate type none. ) but that would be nice as well.

Modifié par painofdungeoneternal, 01 mars 2012 - 10:04 .


#12
kevL

kevL
  • Members
  • 4 061 messages
have you seen GetIsPlayerCreated( ) - it's the only function i've seen that id's an SoZ char ?

// Characters created through the party creation mechanics
// are stored in the Roster system but are flagged as
// PlayerCreated to distinguish them from normal Roster
// contained NPCs. Note that if the character is not
// in the roster /at all/, this function returns false.
// This script function can query that flag.
// oCreature - object id of a creature to check
int GetIsPlayerCreated( object oCreature );

not sure how SoZ adds them to the Roster, or if it's automagic.


btw, you prob. remember that henchmen are basically NwN henchmen - they just tag along and can't access their inventory etc (pretty much a nuisance that need constant protecting)


It would have to be simple on top, and branch out inside to optimize the code. PC only would just switch the faction loop to true.

yes. the thought occurred, to break the routines out into subfunctions then reconsolidate them .....

Modifié par kevL, 01 mars 2012 - 10:57 .


#13
kevL

kevL
  • Members
  • 4 061 messages
i couldn't get the faction loop to work w/ TRUE

- was getting the same thing SD got : count 1, then quit

#14
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages
You need to be in multiplayer for it to ever not be 1, and on a MP server, it will return the count you see in the game servers listing in gamespy for player count ( assuming they are all fully logged in ). TRUE means it only iterates actual humans connected to the game. ( if you and me were playing together on a server it would be 2 and it would just iterate the 2 main characters - really need to test what happens when you possess on that and put that into my documentation, but i've always assumed it is the object you can send messages to and the player will read them ). In MP you can iterate the controlled associates by the nth parameter, and just focus on what a particular player controls, while the faction is whatever is currently in their party.

Ok that makes sense, i'd like to rewrite the description on that function to make more sense as i never understood how it related to the SOZ party until now. Does it return true if it's the actual human being, or just one of the SOZ party members. ( think there is getisowned there as well if it returns true on both )

Modifié par painofdungeoneternal, 01 mars 2012 - 11:40 .


#15
slowdive.fan

slowdive.fan
  • Members
  • 235 messages
Im at work but i saw this...very last paragraph talks about scripts
file

Modifié par slowdive.fan, 02 mars 2012 - 12:08 .


#16
Kaldor Silverwand

Kaldor Silverwand
  • Members
  • 1 592 messages
Similar post about this from a year ago. May shed some light.

At the time I wrote my scripts for this sort of thing I wasn't aware of GetIsPlayerCreated(). So I wrote my own function for that. Basically I found that player created characters do not have tags so that differentiates them from companions, associates, and henchmen. To differentiate between PC's and non-PC's you can check the roster - PCs will not be in the roster. Not sure about what happens in MP though.

Regards

#17
kevL

kevL
  • Members
  • 4 061 messages

painofdungeoneternal wrote...

You need to be in multiplayer for it to ever not be 1,


right, Sry. Ever since GetIsPC( ) changed to mean getiscontrolled, I've been ambiguous about anything that says "PC" or "PConly" ( heck, my familiar is a PC at times ) - re. counting would be nice to have a quick routine that does PC + SoZ_char + companion/cohort .. <- what i meant by PC above.

Ok that makes sense, i'd like to rewrite the description on that function to make more sense as i never understood how it related to the SOZ party until now. Does it return true if it's the actual human being, or just one of the SOZ party members. ( think there is getisowned there as well if it returns true on both )

no, it returns true only for an SoZ-style character that's in the Roster. getisowned is still needed for the true PC. they're exclusive, pretty sure



SD: tks, Saved .Pdf

#18
slowdive.fan

slowdive.fan
  • Members
  • 235 messages
KevL's script worked so back to bug fixing for me...I still need to check it in MP though...

Modifié par slowdive.fan, 02 mars 2012 - 02:33 .


#19
painofdungeoneternal

painofdungeoneternal
  • Members
  • 1 799 messages

Kaldor Silverwand wrote...

Similar post about this from a year ago. May shed some light.

At the time I wrote my scripts for this sort of thing I wasn't aware of GetIsPlayerCreated(). So I wrote my own function for that. Basically I found that player created characters do not have tags so that differentiates them from companions, associates, and henchmen. To differentiate between PC's and non-PC's you can check the roster - PCs will not be in the roster. Not sure about what happens in MP though.

Regards


I set tags on our players to store information, as do quite a few other PWs. ( Grinning fool recommended this store store the players id in the database, and i know many PW's which have taken this advice, good spot to hide information actually as it can store any string you want there. ) By default there is no tag, but i'd avoid this unless you have complete control of everything that is installed. Probably not a problem to use this, especially if it's your module, but it likely something some creative content person is eventually going to take advantage of.

Modifié par painofdungeoneternal, 02 mars 2012 - 02:50 .


#20
kevL

kevL
  • Members
  • 4 061 messages
ps. its not my script ...


(sure is perty tho)