PRC8/nwn/nwnprc/trunk/scripts/prc_pnp_school.nss
Jaysyn904 6ec137a24e Updated AMS marker feats
Updated AMS marker feats.  Removed arcane & divine marker feats.  Updated Dread Necromancer for epic progression. Updated weapon baseitem models.  Updated new weapons for crafting & npc equip.
 Updated prefix.  Updated release archive.
2024-02-11 14:01:05 -05:00

445 lines
19 KiB
Plaintext

//:://////////////////////////////////////////////
//:: Short description
//:: prc_pnp_school
//:://////////////////////////////////////////////
/** @file
@todo Primo: Could you add comments to the code?
This one is sort of painful to figure out
without them.
And the usual header comment + TLKification :D
@author Primogenitor
@date Created - yyyy.mm.dd
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "inc_dynconv"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_SCHOOL_SELECTION = 0;
const int STAGE_OPPOSING_SCHOOL_SELECTION = 1;
const int STAGE_CONFIRMATION = 2;
const int STAGE_COMPLETION = 3;
//////////////////////////////////////////////////
/* Aid functions */
//////////////////////////////////////////////////
//This used Bitwise math
//this thread should help if you dont understand bitwise math
//http://nwn.bioware.com/forums/viewtopic.html?topic=391126&forum=47
void AddSchool(int nSchool, int nSchool2 = 0, int nSchool3 = 0)
{
string sName;
sName += GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool)));
if(nSchool2 && !nSchool3)
sName += " and "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool2)));
if(nSchool2 && nSchool3)
{
sName += ", "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool2)));
sName += ", and "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool3)));
}
int nValue = nSchool + (nSchool2 << 4) + (nSchool3 << 8);
AddChoice(sName, nValue);
if(DEBUG)
{
DoDebug("sName = "+sName+"\n"
+ "nValue = "+IntToString(nValue)+"\n"
+ "nSchool = "+IntToString(nSchool)+"\n"
+ "nSchool2 = "+IntToString(nSchool2)+"\n"
+ "nSchool3 = "+IntToString(nSchool3)+"\n"
+ "nSchool2 << 4 = "+IntToString(nSchool2 << 4)+"\n"
+ "nSchool3 << 8 = "+IntToString(nSchool3 << 8)+"\n"
);
}
}
int GetIPFromSchool(int nSchool)
{
switch(nSchool)
{
case SPELL_SCHOOL_GENERAL: return 241;
case SPELL_SCHOOL_ABJURATION: return 242;
case SPELL_SCHOOL_CONJURATION: return 243;
case SPELL_SCHOOL_DIVINATION: return 244;
case SPELL_SCHOOL_ENCHANTMENT: return 245;
case SPELL_SCHOOL_EVOCATION: return 246;
case SPELL_SCHOOL_ILLUSION: return 247;
case SPELL_SCHOOL_NECROMANCY: return 248;
case SPELL_SCHOOL_TRANSMUTATION:return 249;
}
return 0;
}
int GetIPFromOppSchool(int nSchool)
{
switch(nSchool)
{
case SPELL_SCHOOL_ABJURATION: return 233;
case SPELL_SCHOOL_CONJURATION: return 234;
case SPELL_SCHOOL_DIVINATION: return 235;
case SPELL_SCHOOL_ENCHANTMENT: return 236;
case SPELL_SCHOOL_EVOCATION: return 237;
case SPELL_SCHOOL_ILLUSION: return 238;
case SPELL_SCHOOL_NECROMANCY: return 239;
case SPELL_SCHOOL_TRANSMUTATION:return 240;
}
return 0;
}
//////////////////////////////////////////////////
/* Main function */
//////////////////////////////////////////////////
void main()
{
object oPC = GetPCSpeaker();
/* Get the value of the local variable set by the conversation script calling
* this script. Values:
* DYNCONV_ABORTED Conversation aborted
* DYNCONV_EXITED Conversation exited via the exit node
* DYNCONV_SETUP_STAGE System's reply turn
* 0 Error - something else called the script
* Other The user made a choice
*/
int nValue = GetLocalInt(oPC, DYNCONV_VARIABLE);
// The stage is used to determine the active conversation node.
// 0 is the entry node.
int nStage = GetStage(oPC);
// Check which of the conversation scripts called the scripts
if(nValue == 0) // All of them set the DynConv_Var to non-zero value, so something is wrong -> abort
return;
if(nValue == DYNCONV_SETUP_STAGE)
{
// Check if this stage is marked as already set up
// This stops list duplication when scrolling
if(!GetIsStageSetUp(nStage, oPC))
{
if(nStage == STAGE_SCHOOL_SELECTION) //select a school
{
SetHeader("Select a specialist school.");
int i;
for(i = 0; i < 9; i++) //use 9 to force original schools only
{
AddChoice(GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", i))), i, oPC);
}
MarkStageSetUp(STAGE_SCHOOL_SELECTION, oPC);
}
else if(nStage == STAGE_OPPOSING_SCHOOL_SELECTION)//select oposing school(s)
{
int nSchool = GetLocalInt(oPC, "School");
int a,b,c;
switch(nSchool)
{
case SPELL_SCHOOL_ABJURATION:
AddSchool(SPELL_SCHOOL_CONJURATION);
AddSchool(SPELL_SCHOOL_ENCHANTMENT);
AddSchool(SPELL_SCHOOL_EVOCATION);
AddSchool(SPELL_SCHOOL_ILLUSION);
AddSchool(SPELL_SCHOOL_TRANSMUTATION);
AddSchool(SPELL_SCHOOL_DIVINATION, SPELL_SCHOOL_NECROMANCY);
break;
case SPELL_SCHOOL_CONJURATION:
AddSchool(SPELL_SCHOOL_EVOCATION);
AddSchool(SPELL_SCHOOL_TRANSMUTATION);
AddSchool(SPELL_SCHOOL_ABJURATION, SPELL_SCHOOL_ENCHANTMENT);
AddSchool(SPELL_SCHOOL_ABJURATION, SPELL_SCHOOL_ILLUSION);
AddSchool(SPELL_SCHOOL_ENCHANTMENT, SPELL_SCHOOL_ILLUSION);
// 8^3? Ouch! ... Attempt to reduce the load somewhat
for(a=1;a<=8;a++)
{
if(a == SPELL_SCHOOL_EVOCATION ||
a == SPELL_SCHOOL_TRANSMUTATION ||
a == SPELL_SCHOOL_CONJURATION)
continue;
for(b=a+1;b<=8;b++)
{
if(b == SPELL_SCHOOL_EVOCATION ||
b == SPELL_SCHOOL_TRANSMUTATION ||
b == SPELL_SCHOOL_CONJURATION)
continue;
for(c=b+1;c<=8;c++)
{
if(c == SPELL_SCHOOL_EVOCATION ||
c == SPELL_SCHOOL_TRANSMUTATION ||
c == SPELL_SCHOOL_CONJURATION)
continue;
/*if(!(a == SPELL_SCHOOL_EVOCATION
|| b == SPELL_SCHOOL_EVOCATION
|| c == SPELL_SCHOOL_EVOCATION
|| a == SPELL_SCHOOL_TRANSMUTATION
|| b == SPELL_SCHOOL_TRANSMUTATION
|| c == SPELL_SCHOOL_TRANSMUTATION
|| a == SPELL_SCHOOL_CONJURATION
|| b == SPELL_SCHOOL_CONJURATION
|| c == SPELL_SCHOOL_CONJURATION
|| (a == SPELL_SCHOOL_ABJURATION
&& b == SPELL_SCHOOL_ENCHANTMENT
&& c == SPELL_SCHOOL_ILLUSION
) ))*/
if(!(a == SPELL_SCHOOL_ABJURATION
&& b == SPELL_SCHOOL_ENCHANTMENT
&& c == SPELL_SCHOOL_ILLUSION))
{
AddSchool(a,b,c);
}
}
}
}
break;
case SPELL_SCHOOL_DIVINATION:
for(a=1;a<=8;a++)
{
if(a != SPELL_SCHOOL_DIVINATION)
AddSchool(a);
}
break;
case SPELL_SCHOOL_ENCHANTMENT:
AddSchool(SPELL_SCHOOL_ABJURATION);
AddSchool(SPELL_SCHOOL_CONJURATION);
AddSchool(SPELL_SCHOOL_EVOCATION);
AddSchool(SPELL_SCHOOL_ILLUSION);
AddSchool(SPELL_SCHOOL_TRANSMUTATION);
AddSchool(SPELL_SCHOOL_DIVINATION, SPELL_SCHOOL_NECROMANCY);
break;
case SPELL_SCHOOL_EVOCATION:
AddSchool(SPELL_SCHOOL_CONJURATION);
AddSchool(SPELL_SCHOOL_TRANSMUTATION);
AddSchool(SPELL_SCHOOL_ABJURATION, SPELL_SCHOOL_ENCHANTMENT);
AddSchool(SPELL_SCHOOL_ABJURATION, SPELL_SCHOOL_ILLUSION);
AddSchool(SPELL_SCHOOL_ENCHANTMENT, SPELL_SCHOOL_ILLUSION);
for(a=1;a<=8;a++)
{
if(a == SPELL_SCHOOL_EVOCATION ||
a == SPELL_SCHOOL_TRANSMUTATION ||
a == SPELL_SCHOOL_CONJURATION)
continue;
for(b=a+1;b<=8;b++)
{
if(b == SPELL_SCHOOL_EVOCATION ||
b == SPELL_SCHOOL_TRANSMUTATION ||
b == SPELL_SCHOOL_CONJURATION)
continue;
for(c=b+1;c<=8;c++)
{
if(c == SPELL_SCHOOL_EVOCATION ||
c == SPELL_SCHOOL_TRANSMUTATION ||
c == SPELL_SCHOOL_CONJURATION)
continue;
if(!(a == SPELL_SCHOOL_ABJURATION
&& b == SPELL_SCHOOL_ENCHANTMENT
&& c == SPELL_SCHOOL_ILLUSION))
{
AddSchool(a,b,c);
}
}
}
}
break;
case SPELL_SCHOOL_ILLUSION:
AddSchool(SPELL_SCHOOL_ABJURATION);
AddSchool(SPELL_SCHOOL_CONJURATION);
AddSchool(SPELL_SCHOOL_EVOCATION);
AddSchool(SPELL_SCHOOL_ENCHANTMENT);
AddSchool(SPELL_SCHOOL_TRANSMUTATION);
AddSchool(SPELL_SCHOOL_DIVINATION, SPELL_SCHOOL_NECROMANCY);
break;
case SPELL_SCHOOL_NECROMANCY:
for(a=1;a<=8;a++)
{
if(a != SPELL_SCHOOL_NECROMANCY)
AddSchool(a);
}
break;
case SPELL_SCHOOL_TRANSMUTATION:
AddSchool(SPELL_SCHOOL_CONJURATION);
AddSchool(SPELL_SCHOOL_EVOCATION);
AddSchool(SPELL_SCHOOL_ABJURATION, SPELL_SCHOOL_ENCHANTMENT);
AddSchool(SPELL_SCHOOL_ABJURATION, SPELL_SCHOOL_ILLUSION);
AddSchool(SPELL_SCHOOL_ENCHANTMENT, SPELL_SCHOOL_ILLUSION);
for(a=1;a<=8;a++)
{
if(a == SPELL_SCHOOL_EVOCATION ||
a == SPELL_SCHOOL_TRANSMUTATION ||
a == SPELL_SCHOOL_CONJURATION)
continue;
for(b=a+1;b<=8;b++)
{
if(b == SPELL_SCHOOL_EVOCATION ||
b == SPELL_SCHOOL_TRANSMUTATION ||
b == SPELL_SCHOOL_CONJURATION)
continue;
for(c=b+1;c<=8;c++)
{
if(c == SPELL_SCHOOL_EVOCATION ||
c == SPELL_SCHOOL_TRANSMUTATION ||
c == SPELL_SCHOOL_CONJURATION)
continue;
if(!(a == SPELL_SCHOOL_ABJURATION
&& b == SPELL_SCHOOL_ENCHANTMENT
&& c == SPELL_SCHOOL_ILLUSION))
{
AddSchool(a,b,c);
}
}
}
}
break;
}
SetHeader("Select a set of opposition school(s).");
MarkStageSetUp(STAGE_OPPOSING_SCHOOL_SELECTION, oPC);
}
else if(nStage == STAGE_CONFIRMATION)//confirmation
{
int nSchool = GetLocalInt(oPC, "School" );
int nSchool1 = GetLocalInt(oPC, "School1");
int nSchool2 = GetLocalInt(oPC, "School2");
int nSchool3 = GetLocalInt(oPC, "School3");
AddChoice(GetStringByStrRef(4752), TRUE); // "Yes"
AddChoice(GetStringByStrRef(4753), FALSE); // "No"
string sName;
sName += GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool1)));
if(nSchool2 && !nSchool3)
sName += " and "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool2)));
if(nSchool2 && nSchool3)
{
sName += ", "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool2)));
sName += ", and "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool3)));
}
string sText = "You have selected "+GetStringByStrRef(StringToInt(Get2DACache("spellschools", "StringRef", nSchool)))
+" as your specialist school.\n";
if(nSchool != SPELL_SCHOOL_GENERAL)
sText += "You have selected "+sName+" as your opposition school(s).\n";
sText += "Is this correct?";
SetHeader(sText);
MarkStageSetUp(STAGE_CONFIRMATION, oPC);
}
else if(nStage == STAGE_COMPLETION)//completion
{
//end stage, do not set responces
string sText = "Your PnP Spell Schools are now setup";
SetHeader(sText);
}
}
// Do token setup
SetupTokens();
SetDefaultTokens();
}
else if(nValue == DYNCONV_EXITED)
{
// End of conversation cleanup
DeleteLocalInt(oPC, "School");
DeleteLocalInt(oPC, "School1");
DeleteLocalInt(oPC, "School2");
DeleteLocalInt(oPC, "School3");
}
else if(nValue == DYNCONV_ABORTED)
{
// Abort conversation cleanup
DeleteLocalInt(oPC, "School");
DeleteLocalInt(oPC, "School1");
DeleteLocalInt(oPC, "School2");
DeleteLocalInt(oPC, "School3");
}
// Handle PC responses
else
{
int nChoice = GetChoice(oPC);
if(nStage == STAGE_SCHOOL_SELECTION)//select a school
{
if(nChoice == SPELL_SCHOOL_GENERAL)
nStage = STAGE_CONFIRMATION;// generalist, go to confirmation
else
nStage = STAGE_OPPOSING_SCHOOL_SELECTION;//select opposing school
SetLocalInt(oPC, "School", nChoice);
}
else if(nStage == STAGE_OPPOSING_SCHOOL_SELECTION)//select opposing school(s)
{
int nSchool1 = nChoice & 15;
int nSchool2 = (nChoice & 240) >> 4;
int nSchool3 = (nChoice & 3840) >> 8;
SetLocalInt(oPC, "School1", nSchool1);
SetLocalInt(oPC, "School2", nSchool2);
SetLocalInt(oPC, "School3", nSchool3);
nStage = STAGE_CONFIRMATION;
if(DEBUG)
{
DoDebug("nChoice = "+IntToString(nChoice)+"\n"
+ "nSchool1 = "+IntToString(nSchool1)+"\n"
+ "nSchool2 = "+IntToString(nSchool2)+"\n"
+ "nSchool3 = "+IntToString(nSchool3)+"\n"
+ "nValue & 240 = "+IntToString(nValue & 240)+"\n"
+ "nValue & 3840 = "+IntToString(nValue & 3840)+"\n"
);
}
}
else if(nStage == STAGE_CONFIRMATION)//confirmation
{
if(nChoice == TRUE)
{
nStage = STAGE_COMPLETION;
int nSchool = GetLocalInt(oPC, "School" );
int nSchool1 = GetLocalInt(oPC, "School1");
int nSchool2 = GetLocalInt(oPC, "School2");
int nSchool3 = GetLocalInt(oPC, "School3");
object oSkin = GetPCSkin(oPC);
itemproperty ipSchool = PRCItemPropertyBonusFeat(GetIPFromSchool(nSchool));
itemproperty ipSchool1 = PRCItemPropertyBonusFeat(GetIPFromOppSchool(nSchool1));
itemproperty ipSchool2 = PRCItemPropertyBonusFeat(GetIPFromOppSchool(nSchool2));
itemproperty ipSchool3 = PRCItemPropertyBonusFeat(GetIPFromOppSchool(nSchool3));
IPSafeAddItemProperty(oSkin, ipSchool, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
if(nSchool1 != 0)
IPSafeAddItemProperty(oSkin, ipSchool1, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
if(nSchool2 != 0)
IPSafeAddItemProperty(oSkin, ipSchool2, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
if(nSchool3 != 0)
IPSafeAddItemProperty(oSkin, ipSchool3, 0.0f, X2_IP_ADDPROP_POLICY_KEEP_EXISTING, FALSE, FALSE);
}
else
{
nStage = STAGE_SCHOOL_SELECTION;
MarkStageNotSetUp(STAGE_SCHOOL_SELECTION, oPC);
MarkStageNotSetUp(STAGE_OPPOSING_SCHOOL_SELECTION, oPC);
MarkStageNotSetUp(STAGE_CONFIRMATION, oPC);
}
DeleteLocalInt(oPC, "School");
DeleteLocalInt(oPC, "School1");
DeleteLocalInt(oPC, "School2");
DeleteLocalInt(oPC, "School3");
}
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}