Aller au contenu

Photo

Querying Wizard Specialization School


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

#1
AGhost_7

AGhost_7
  • Members
  • 62 messages

Is there a way to query it? I tried using GetCasterClassSpellSchool, but after some debugging issues I realized that the function doesn't work at all and actually makes the script silently fail (i.e. the portion below the function call won't be executed).

 

I then tried to see if there was any feat that you get when you pick your specialization school. Using the following script I was able to figure out that no, you don't:

 
void FeatPrintRange(object oTarget, int nFrom, int nUntil)
{
    string sFeat = "";
    int i;
    for(i = nFrom; i < nUntil; i++)
    {
        if(GetHasFeat(i, oTarget))
        {
            sFeat = GetFeatName(i);
            Debug(sFeat + "(" + IntToString(i) + ")");
        }
    }
}
void FeatPrinter(object oTarget)
{
    Debug("\n--- Feat Printer ---\n");
    FeatPrintRange(oTarget, 0, 2256);
    DelayCommand(0.5f, FeatPrintRange(oTarget, 3500, 3939));
    DelayCommand(1.0f, FeatPrintRange(oTarget, 5500, 5550));
}
 
What should I try next? Does someone have any idea how to query the specialization school?
 


#2
Loki_999

Loki_999
  • Members
  • 430 messages

Had a look and a think and can't really see any way of getting this info.

 

The only thing i can think that might work would be to hook into the GUI XML, and on selection of spellschool add an extra callback that adds a feat to the character to indicate their spell school.

 

So, create 1 feat for each school (including general).

 

Edit: chargen_school.xml/chargen_school1.xml/chargen_school2.xml (depending on which expansions you have).

 

When an entry is selected you probably need to add a callback to select which row was selected around line 159... something like:

 

OnLeftClick=UIObject_Misc_ExecuteServerScript("gui_scriptname",listboxrow:BOXNAME,"value")

 

Have your script then store the value somewhere (no idea where at this stage, because character is not complete - there is no object to attach it to... i can only think setting a var on the module itself... if this is for MP its got potential for problems if multiple people are creating a wizard at the same time.

 

So script does something like: SetLocalInt(oModule, "CHARGENSPELLSCHOOL", iValue);

 

Then when the character appears in the module (OnPCLoaded event) check to see if they have one of your feats already, and if not, check that variable, and grant the appropriate feat.


  • AGhost_7 aime ceci

#3
AGhost_7

AGhost_7
  • Members
  • 62 messages

Awesome! I can probably work out something with this info. Thanks Loki.

 

For the module variable, I was thinking that I could do "WizSchool_" + ObjectToString(oPC) or something along those lines. Hopefully it doesn't change after the character is finalized. I'll try to add the feat during character creation first though. Maybe that could work?



#4
Loki_999

Loki_999
  • Members
  • 430 messages

This may depend on whether its a level 0 character (ie: pre-character gen) or an already generated character.

 

That is, if you are taking your first level of Wiz with an existing character, then for sure you should be able to grab oPC with GetPCLevellingUp() or OBJECT_SELF. But if this is a new character, there may not be an object to grab the info from... but anyway, yeah, try OBJECT_SELF, see if that gives you something usable.

 

And actually, the OnPCLoaded event is only valid for new characters. Need to consider existing characters, so that is probably better being handled on the OnLevelUp event.... but i'd bet good money that this event is also triggered after creating a new character, so hopefully means you only need one script to handle the post creation granting of feats.



#5
Loki_999

Loki_999
  • Members
  • 430 messages

Oh yeah, and ill try and help if you get stuck with the XML, but i've found that quite often its a matter of just playing and tweaking with things, because the whole system is so badly documented.



#6
AGhost_7

AGhost_7
  • Members
  • 62 messages

Thanks for the offer. Honestly, we tried modifying the XML and it doesn't seem like it does anything at all. Even clearing the whole XML out won't do a thing to the GUI. Are you sure this is the file which is responsible for that?



#7
Loki_999

Loki_999
  • Members
  • 430 messages

Not 100% certain, but it should be. But it could always be one of those dreaded hardcoded issues.

 

So... even if you blank the XML it still shows the default screen? Are you trying to override it? Maybe it will only work if you modify the base game install version... you tried that? (i know, no good for use by most, but might give some clues).

 

And remember, there are 3 versions of the file... no idea if the game engine looks for a specific one depending on which expansions you have.



#8
kevL

kevL
  • Members
  • 4 056 messages

And remember, there are 3 versions of the file... no idea if the game engine looks for a specific one depending on which expansions you have.


I used to think the game always used the x2 version -- until with some file (i forget..) it didn't ....

( iirc the engine went back to find a stock .Xml in the installation folder instead )


best practice since, is to change copies of all three

#9
AGhost_7

AGhost_7
  • Members
  • 62 messages

Tried all three versions of the xml, no dice. Even tried the ones in install directory, no change to gui.



#10
kevL

kevL
  • Members
  • 4 056 messages

Are you looking at the packages screen when creating a character, or going to Customize and looking at the spellschool screen there?

Because i just edited 'chargen_schoolx2.xml' to remove the left/right rotate buttons and it worked. They were gone (but are present on the before & after screens). They reside in player-folder on my setup (no duplicates... C:\Documents and Settings\kL\My Documents\Neverwinter Nights 2\ui\custom)


( btw, the .Xml i was having probs with was the worldmap; it might have just been a typo idk, because it looks like I ended up editing worldmapnx1 even though SoZ is installed. ) edit: bleh don't know what i did / shrug



#11
Loki_999

Loki_999
  • Members
  • 430 messages

There you go then, it is definitely editable, so you are missing something probably.



#12
AGhost_7

AGhost_7
  • Members
  • 62 messages

Yea, I guess I'll have to ask Brian what he did exactly. Thanks again.



#13
Loki_999

Loki_999
  • Members
  • 430 messages

Any luck?



#14
AGhost_7

AGhost_7
  • Members
  • 62 messages

Honestly, I'm finishing my college semester here so I didn't really have the time to get into it. I've got some assignments which are due soon. It also looks like Brian isn't going to check on this soon (he's busy finishing the third campaign), so I'll look into it without his help when I get the time. I'll let you know the results as soon as I can.



#15
AGhost_7

AGhost_7
  • Members
  • 62 messages

I just tried it, and you're right kevL, it does work. I'll have to see if the reason why its not working with the hak files is because there's a copy in there already... Somewhere in the RoT haks.



#16
kevL

kevL
  • Members
  • 4 056 messages

it's gotta be a duplicate -- it's soo symptomatic, gotta be



#17
AGhost_7

AGhost_7
  • Members
  • 62 messages

I got it to work with the haks. I added this to the UIListBox for the spell school, as suggested by loki:

 

OnLeftClick=UIObject_Misc_ExecuteServerScript("gui_ag7_school",listboxrow:SCHOOL_LIST)

 

Not sure if I've got it right, but then my gui_ag7_school script looks like this:

void main(string sValue)
{
    SetLocalString(GetModule(), "WizSch", sValue);
    object oPC = GetControlledCharacter(OBJECT_SELF);
    SetLocalString(GetModule(), "WizSch_" + ObjectToString(oPC), sValue);
    SetLocalString(oPC, "ag7_test", "hello!");
}
 
Then, when the player loads in the following script is used to print the stored variables:
 
void Test()
{
    Debug("\nChecking variables...\n");


    string sValue = GetLocalString(GetModule(), "WizSch_" + ObjectToString(OBJECT_SELF));
    string sValue2 = GetLocalString(GetModule(), "WizSch");
    string sHello = GetLocalString(OBJECT_SELF, "ag7_test");
    Debug("Module: " + sValue);
    Debug("Module (no ObjecToString):" + sValue2);
    Debug(sHello);


    DelayCommand(20.0f, Test());
}
void main()
{
    Test();
}
 
By the looks of it, gui_ag7_school isnt doing anything at all (all local variables are showing as empty). Now, I'm testing this on single player - could it be that the module object isn't even valid at character creation?


#18
Dann-J

Dann-J
  • Members
  • 3 161 messages

 

 
By the looks of it, gui_ag7_school isnt doing anything at all (all local variables are showing as empty). Now, I'm testing this on single player - could it be that the module object isn't even valid at character creation?

 

 

I doubt that the module exists in any scriptable way until after it has been fully loaded (well after character creation).



#19
kevL

kevL
  • Members
  • 4 056 messages

well, Loki & Lance probly know more about gui-scripts
but one thing i found out is that callbacks need to send INTS

ie: 'gui_ag7_school'

void main(int iValue)
{
    // map your INT to a string
    // etc.
}

:wacko:

as to whether the module exists, check for it [ if (GetIsObjectValid(GetModule())) ] and if TRUE send debug.

#20
AGhost_7

AGhost_7
  • Members
  • 62 messages

From the xml it looked like UIObject_Misc_ExecuteServerScript took a string vararg, I guess that was wrong -  just opened gui_bhvr_puppet_off to find void main(int iExamined). Off for another round of testing.

 

EDIT: looks like the script really isn't executing.

 

void main(int nValue)
{
    DelayCommand(60.0f, Debug("Script has executed"));
}

I go through the character creation as fast as possible, making sure to click the specialization school list a few times. It never ends up printing anything after the game loads. What did I do of wrong?



#21
kevL

kevL
  • Members
  • 4 056 messages

got it working.

'chargen_schoolx2.xml'
- in UIScene, set scriptloadable="true"
- in UIButton CHOICE_NEXT, this line:
 

OnLeftClick0='UIObject_Misc_ExecuteServerScript("gui_chooseschool",listboxrow:SCHOOL_LIST)'

This is 'gui_chooseschool'

// 'gui_chooseschool'

void main(int iSchool)
{
    string sSchool;

    switch (iSchool)
    {
        case 0: sSchool = "general";        break;
        case 1: sSchool = "abjuration";     break;
        case 2: sSchool = "conjuration";    break;
        case 3: sSchool = "divination";     break;
        case 4: sSchool = "enchantment";    break;
        case 5: sSchool = "evocation";      break;
        case 6: sSchool = "illusion";       break;
        case 7: sSchool = "necromancy";     break;
        case 8: sSchool = "transmutation";  break;
    }

    object oModule = GetModule();
    if (GetIsObjectValid(oModule))
        SetLocalString(oModule, "school", sSchool);
    else
        SetGlobalString("school", sSchool);
}

note that the first listbox row is #0. To test IG, i used this script:
 

// 'school'

void main()
{
    object oModule = GetModule();

    if (GetLocalString(oModule, "school") != "")
        SendMessageToPC(GetFirstPC(FALSE), "Module has school-string: " + GetLocalString(oModule, "school"));
    else
        SendMessageToPC(GetFirstPC(FALSE), "school-string is Global: " + GetGlobalString("school"));
}

module object was largely valid. Funny thing is, the very first time this [sorta] worked, module was not valid .... But i reloaded the game fresh a few times and module-object came up valid on all subsequent occasions, whether a module or a campaign (single player, nothing special).

The debug correctly told me what school I'd chosen; something similar would have to be done for the Packages screen, if you're keeping that screen active. PS you'll want to label the varname so it corresponds to the particular player/PC .... ( but you know that ..)



#22
kevL

kevL
  • Members
  • 4 056 messages

ah, module object was always valid ... it's just that on that first round i had OnLeftClick in the wrong place in the XML so string was blank.



#23
kevL

kevL
  • Members
  • 4 056 messages

note3 if ObjectToString(oPC) is no good try their CD-keys (?)



#24
BartjeD

BartjeD
  • Members
  • 249 messages

I have seen this topic a few times but I forgot to respond. I also got this working, half a year ago. Based on something Lance did, I think. He provided XML code for it once.
 
What I've done is make a mod which allows wizards to select their oppositions schools. It doesn't work extremely well with the default spell system because you can then learn forbidden spells, and cast them. Because it requires removing all forbidden schools in the relevant .2da file. And then you stop casting via the spell hook. But it works better via the custom spell casting system. Because that also prevents you from learning forbidden spells appropriately. That makes it essentially painless.
 
This is the code I wrote:

/*
gui_getchardata by Rasael, original by Lance Botelle
*/

#include "inc_spellschools"

void main(string sField, string sValue)
{
//Trim the value string.
sValue = GetStringRight(sValue, GetStringLength(sValue) - 17);

object oChar = OBJECT_SELF;
//SendMessageToPC(oChar, "Running UI Feedback");

//SendMessageToPC(oChar, "Running Script School");
//SpeakString("Running Script School");
// Categorize and store the character data for easier retrieval.
// Assign feats (as Raelius Archmannon suggested) or store in your DB.
//SendMessageToPC(OBJECT_SELF, sField + " = " + sValue);
int iTargetSchool = -1;
if ( sField == "SCHOOL" ) // don't even bother if the field returned is not school, possibly make this fire once for each field desired
{

// Lets do some validation, this should already be set up correctly, but checking for monkey business
// If the caster is a specialist some other things should be set as well

// is the caster a wizard
if ( GetLevelByClass( CLASS_TYPE_WIZARD, oChar ) > 0 )
{
if ( sValue == "Abjuration" )
{
iTargetSchool = SPELL_SCHOOL_ABJURATION;
}
else if ( sValue == "Conjuration"  )
{
iTargetSchool = SPELL_SCHOOL_CONJURATION;
}
else if ( sValue == "Divination" )
{
iTargetSchool = SPELL_SCHOOL_DIVINATION;
}
else if ( sValue == "Enchantment"  )
{
iTargetSchool = SPELL_SCHOOL_ENCHANTMENT;
}
else if ( sValue == "Evocation"  )
{
iTargetSchool = SPELL_SCHOOL_EVOCATION;
}
else if ( sValue == "Illusion"  )
{
iTargetSchool = SPELL_SCHOOL_ILLUSION;
}
else if ( sValue == "Necromancy"  )
{
iTargetSchool = SPELL_SCHOOL_NECROMANCY;
}
else if ( sValue == "Transmutation" )
{
iTargetSchool = SPELL_SCHOOL_TRANSMUTATION;
}
else
{
iTargetSchool = SPELL_SCHOOL_GENERAL;
//if ( GetLevelByClass( CLASS_TYPE_RED_WIZARD, oChar ) > 0 )
//{
// log message to dms now, we hve an issue, red wizards have to have a speciality.
// set up benefits so it does not matter too much
//}
}
//iTargetSchool = 100;
}
}
//SendMessageToPC(oChar, "Spellschool = "+sValue+" = "+IntToString(iTargetSchool));
CloseGUIScreen(oChar, "archery_copy");
SetLocalInt(oChar, "focus_spellschool", iTargetSchool);
int iHasFeats = iHasFocalSchoolFeat(oChar, iTargetSchool);
}

And this is the include:

/*
inc_spellschools by Rasael
*/

//translates string to school int
int StringToSchool(string sSchool)
{
if(sSchool == "G") {return SPELL_SCHOOL_GENERAL;}
if(sSchool == "A") {return SPELL_SCHOOL_ABJURATION;}
if(sSchool == "C") {return SPELL_SCHOOL_CONJURATION;}
if(sSchool == "D") {return SPELL_SCHOOL_DIVINATION;}
if(sSchool == "E") {return SPELL_SCHOOL_ENCHANTMENT;}
if(sSchool == "V") {return SPELL_SCHOOL_EVOCATION;}
if(sSchool == "I") {return SPELL_SCHOOL_ILLUSION;}
if(sSchool == "N") {return SPELL_SCHOOL_NECROMANCY;}
if(sSchool == "T") {return SPELL_SCHOOL_TRANSMUTATION;}

return 3;
}

//returns the NWN2 default opposed schools
int DefaultOpposedSchool1(int iSchool)
{
if(iSchool == SPELL_SCHOOL_ABJURATION) {return SPELL_SCHOOL_CONJURATION;}
if(iSchool == SPELL_SCHOOL_CONJURATION) {return SPELL_SCHOOL_TRANSMUTATION;}
if(iSchool == SPELL_SCHOOL_DIVINATION) {return SPELL_SCHOOL_ILLUSION;}
if(iSchool == SPELL_SCHOOL_ENCHANTMENT) {return SPELL_SCHOOL_ILLUSION;}
if(iSchool == SPELL_SCHOOL_EVOCATION) {return SPELL_SCHOOL_CONJURATION;}
if(iSchool == SPELL_SCHOOL_ILLUSION) {return SPELL_SCHOOL_ENCHANTMENT;}
if(iSchool == SPELL_SCHOOL_NECROMANCY) {return SPELL_SCHOOL_DIVINATION;}
if(iSchool == SPELL_SCHOOL_TRANSMUTATION) {return SPELL_SCHOOL_CONJURATION;}

return 3;
}

//returns the NWN2 default opposed schools
int DefaultOpposedSchool2(int iSchool)
{
if(iSchool == SPELL_SCHOOL_ABJURATION) {return SPELL_SCHOOL_ILLUSION;}
if(iSchool == SPELL_SCHOOL_CONJURATION) {return SPELL_SCHOOL_ILLUSION;}
if(iSchool == SPELL_SCHOOL_DIVINATION) {return SPELL_SCHOOL_ENCHANTMENT;}
if(iSchool == SPELL_SCHOOL_ENCHANTMENT) {return SPELL_SCHOOL_ABJURATION;}
if(iSchool == SPELL_SCHOOL_EVOCATION) {return SPELL_SCHOOL_ILLUSION;}
if(iSchool == SPELL_SCHOOL_ILLUSION) {return SPELL_SCHOOL_ABJURATION;}
if(iSchool == SPELL_SCHOOL_NECROMANCY) {return SPELL_SCHOOL_ILLUSION;}
if(iSchool == SPELL_SCHOOL_TRANSMUTATION) {return SPELL_SCHOOL_ILLUSION;}

return SPELL_SCHOOL_ILLUSION;
}

//return feat ID tied to opposed school constant, -1 on error or general school
int iFeatForOpposedSchool(int iOpposeSchool)
{
if(iOpposeSchool == SPELL_SCHOOL_ABJURATION) {return 2467;}
if(iOpposeSchool == SPELL_SCHOOL_CONJURATION) {return 2466;}
if(iOpposeSchool == SPELL_SCHOOL_DIVINATION) {return 2465;}
if(iOpposeSchool == SPELL_SCHOOL_ENCHANTMENT) {return 2464;}
if(iOpposeSchool == SPELL_SCHOOL_EVOCATION) {return 2463;}
if(iOpposeSchool == SPELL_SCHOOL_ILLUSION) {return 2462;}
if(iOpposeSchool == SPELL_SCHOOL_NECROMANCY) {return 2461;}
if(iOpposeSchool == SPELL_SCHOOL_TRANSMUTATION) {return 2460;}

return -1;
}

int iHasFocalSchoolFeat(object oTargetWizard, int iFavouredSchool)
{
if(iFavouredSchool == SPELL_SCHOOL_ABJURATION && GetHasFeat(2477, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2477, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_CONJURATION && GetHasFeat(2476, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2476, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_DIVINATION && GetHasFeat(2475, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2475, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_ENCHANTMENT && GetHasFeat(2474, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2474, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_EVOCATION && GetHasFeat(2473, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2473, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_ILLUSION && GetHasFeat(2472, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2472, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_NECROMANCY && GetHasFeat(2471, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2471, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_TRANSMUTATION && GetHasFeat(2470, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2470, FALSE, TRUE, TRUE);}	
if(iFavouredSchool == SPELL_SCHOOL_GENERAL && GetHasFeat(2478, oTargetWizard, TRUE) == FALSE)
	{FeatAdd( oTargetWizard, 2478, FALSE, TRUE, TRUE);}	
	

int iForbiddenSchoolFeats = 0;
if(GetHasFeat(2460, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Trans
if(GetHasFeat(2461, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Necro
if(GetHasFeat(2462, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Illu
if(GetHasFeat(2463, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Evoc
if(GetHasFeat(2464, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Enchan
if(GetHasFeat(2465, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Divin
if(GetHasFeat(2466, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Conjur
if(GetHasFeat(2467, oTargetWizard, TRUE) == TRUE) {iForbiddenSchoolFeats = iForbiddenSchoolFeats + 1;} //Abjur

int iNeedForbidden = 1;
if(iFavouredSchool == SPELL_SCHOOL_GENERAL) {iNeedForbidden = 0;}
int iRW = GetLevelByClass(CLASS_TYPE_RED_WIZARD, oTargetWizard);
if(iRW > 0) {iNeedForbidden = 2;}

int iFeatAdded;

if(iNeedForbidden > iForbiddenSchoolFeats)
	{
	if(iForbiddenSchoolFeats == 1 && iNeedForbidden == 2)
		{
		int iDefault2School = DefaultOpposedSchool2(iFavouredSchool);
		int iDefault2SchoolFeat = iFeatForOpposedSchool(iDefault2School);
		if(GetHasFeat(iDefault2SchoolFeat, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, iDefault2SchoolFeat, FALSE, TRUE, TRUE);}
		else if(GetHasFeat(2465, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, 2465, FALSE, TRUE, TRUE);}
		else {FeatAdd( oTargetWizard, 2467, FALSE, TRUE, TRUE);}
		iFeatAdded = 1;
		}
	else if(iForbiddenSchoolFeats == 0 && iNeedForbidden == 1)
		{
		int iDefault1School = DefaultOpposedSchool1(iFavouredSchool);
		int iDefault1SchoolFeat = iFeatForOpposedSchool(iDefault1School);
		if(GetHasFeat(iDefault1SchoolFeat, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, iDefault1SchoolFeat, FALSE, TRUE, TRUE);}
		else if(GetHasFeat(2465, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, 2465, FALSE, TRUE, TRUE);}
		else {FeatAdd( oTargetWizard, 2467, FALSE, TRUE, TRUE);}
		iFeatAdded = 1;
		}
	else if(iForbiddenSchoolFeats == 0 && iNeedForbidden == 2)
		{
		int iDefault1School = DefaultOpposedSchool1(iFavouredSchool);
		int iDefault1SchoolFeat = iFeatForOpposedSchool(iDefault1School);
		int iDefault2School = DefaultOpposedSchool2(iFavouredSchool);
		int iDefault2SchoolFeat = iFeatForOpposedSchool(iDefault2School);
		if(GetHasFeat(iDefault2SchoolFeat, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, iDefault2SchoolFeat, FALSE, TRUE, TRUE);}
		if(GetHasFeat(iDefault1SchoolFeat, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, iDefault1SchoolFeat, FALSE, TRUE, TRUE);}
		iFeatAdded = 1;
		}	
	}
	
if(iFeatAdded == 1)
	{
	if(GetHasFeat(2469, oTargetWizard, TRUE) == FALSE) {FeatAdd( oTargetWizard, 2469, FALSE, TRUE, TRUE);}
	}	

SetLocalInt(oTargetWizard, "special_school_check", TRUE);
return TRUE;
}

And this is the XML, which you can call up whenever you need it in game and then set the result with a (local) variable on the PC:

<?xml version="1.0" encoding="utf-8">

<UIScene name="spell_school_get" x="ALIGN_LEFT" y="ALIGN_TOP" width="40" height="40" idleexpiretime="1.0" scriptloadable="true" 
backoutkey="false" priority="SCENE_SCRIPT" modal="false" 
OnAdd="UIObject_Misc_RequestCharacterUpdates(0,true,STATS)"
OnRemove="UIObject_Misc_RequestCharacterUpdates(0,false)"
/>

	<UIPane width="40" height="40" hidden="true" focusable="false" >
		<UIText width="PARENT_WIDTH" height="PARENT_HEIGHT" update="true" hidden="true"
		OnUpdate0="UIObject_OnUpdate_GetGlobalSpellClass(Global:2)" 
		OnUpdate1="UIObject_Misc_SetLocalVarString(local:0)"
		OnUpdate2="UIObject_Misc_ExecuteServerScript(gui_getchardata1,local:0)"
		/> 
	</UIPane>

There's also a conversation via which the player picks his forbidden schools. I can't post that here. If there's any interest I can probably upload everything to the vault some time. Just need to take some time to organize it all.



#25
AGhost_7

AGhost_7
  • Members
  • 62 messages

note3 if ObjectToString(oPC) is no good try their CD-keys (?)

The problem with this is that if the player closes the game during character creation, and then makes a new character, its going to have the same data as the previous one. I guess that the solution would be to add a clear callback to delete the variable at the very beginning of the character creation.