forked from Jaysyn/PRC8
Updated Release Archive. Fixed Mage-killer prereqs. Removed old LETO & ConvoCC related files. Added organized spell scroll store. Fixed Gloura spellbook. Various TLK fixes. Reorganized Repo. Removed invalid user folders. Added DocGen back in.
328 lines
15 KiB
Plaintext
328 lines
15 KiB
Plaintext
//:://////////////////////////////////////////////
|
|
//:: Runescarred berserker conversation
|
|
//:: run_convb
|
|
//:://////////////////////////////////////////////
|
|
/** @file
|
|
Conversation to handle runescarring
|
|
|
|
|
|
@author Primogenitor
|
|
@date Created - 2006.09.05
|
|
*/
|
|
//:://////////////////////////////////////////////
|
|
//:://////////////////////////////////////////////
|
|
|
|
#include "prc_alterations"
|
|
#include "inc_dynconv"
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Constant defintions */
|
|
//////////////////////////////////////////////////
|
|
|
|
|
|
//yes this is a global variable
|
|
//used to count the scars used in GetCanScribeLocation
|
|
//since the return is used for the header string
|
|
int nRuneCount = 0;
|
|
|
|
const int STAGE_ENTRY = 0;
|
|
const int STAGE_SPELL = 1;
|
|
const int STAGE_LEVEL = 2;
|
|
const int STAGE_CONFIRM = 3;
|
|
|
|
//////////////////////////////////////////////////
|
|
/* Aid functions */
|
|
//////////////////////////////////////////////////
|
|
|
|
string GetCanScribeLocation(string sHeader, int nLoc, object oPC)
|
|
{
|
|
string sName;
|
|
string sVar;
|
|
switch(nLoc)
|
|
{
|
|
case 1: sName = "Face"; sVar = "Runescar_Face"; break;
|
|
case 2: sName = "Left Arm"; sVar = "Runescar_Arm_Left"; break;
|
|
case 3: sName = "Left Chest"; sVar = "Runescar_Chest_Left"; break;
|
|
case 4: sName = "Left Hand"; sVar = "Runescar_Hand_Left"; break;
|
|
case 5: sName = "Right Arm"; sVar = "Runescar_Arm_Right"; break;
|
|
case 6: sName = "Right Chest"; sVar = "Runescar_Chest_Right"; break;
|
|
case 7: sName = "Right Hand"; sVar = "Runescar_Hand_Right"; break;
|
|
}
|
|
int nSpellID = GetPersistantLocalInt(oPC, sVar);
|
|
if(nSpellID)
|
|
{
|
|
nRuneCount++;
|
|
nSpellID = nSpellID-1;
|
|
//string sSpellIDName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
|
|
sHeader += (sName+": "+GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)))+"\n");
|
|
}
|
|
else
|
|
AddChoice(sName, nLoc, oPC);
|
|
return sHeader;
|
|
}
|
|
|
|
void AddRunescarSpellChoice(int nSpellID, object oPC, int nSpellLevel = -1)
|
|
{
|
|
//default to innate level
|
|
if(nSpellLevel == -1)
|
|
nSpellLevel = StringToInt(Get2DACache("spells", "Innate", nSpellID));
|
|
|
|
string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
|
|
|
|
sName += " (level "+IntToString(nSpellLevel)+")";
|
|
|
|
//test if spare slot this day
|
|
if(GetLocalInt(oPC, "Runescar_slot_"+IntToString(nSpellLevel))
|
|
&& GetAbilityScore(oPC, ABILITY_WISDOM)>=10+nSpellLevel)
|
|
AddChoice(sName, nSpellID, oPC);
|
|
//store the level to cast it at
|
|
SetLocalInt(oPC, "Runescar_spell_level_"+IntToString(nSpellID), nSpellLevel);
|
|
}
|
|
|
|
//////////////////////////////////////////////////
|
|
/* 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)
|
|
{
|
|
if(!GetIsStageSetUp(nStage, oPC))
|
|
{
|
|
if(nStage == STAGE_ENTRY)
|
|
{
|
|
string sHeader = "You currently have the following Runescars scribed:\n";
|
|
nRuneCount = 0;
|
|
sHeader = GetCanScribeLocation(sHeader, 1, oPC);
|
|
sHeader = GetCanScribeLocation(sHeader, 2, oPC);
|
|
sHeader = GetCanScribeLocation(sHeader, 3, oPC);
|
|
sHeader = GetCanScribeLocation(sHeader, 4, oPC);
|
|
sHeader = GetCanScribeLocation(sHeader, 5, oPC);
|
|
sHeader = GetCanScribeLocation(sHeader, 6, oPC);
|
|
sHeader = GetCanScribeLocation(sHeader, 7, oPC);
|
|
|
|
if(nRuneCount < 7)
|
|
sHeader += "\nWhere would you like to scribe a new Runescar?";
|
|
else
|
|
sHeader += "\nYou cannot scribe a new Runescar at this time.";
|
|
|
|
SetHeader(sHeader);
|
|
|
|
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
|
|
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
|
|
}
|
|
else if(nStage == STAGE_SPELL)
|
|
{
|
|
//select the spell to scribe
|
|
SetHeader("Which spell would you like to scribe as a Runescar?");
|
|
AddRunescarSpellChoice(SPELL_CURE_MODERATE_WOUNDS, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_DIVINE_FAVOR, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_PROTECTION__FROM_CHAOS, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_PROTECTION_FROM_EVIL, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_PROTECTION_FROM_GOOD, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_PROTECTION_FROM_LAW, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_RESIST_ELEMENTS, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_SEE_INVISIBILITY, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_TRUE_STRIKE, oPC, 1);
|
|
AddRunescarSpellChoice(SPELL_ENDURANCE, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_BULLS_STRENGTH, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_CURE_SERIOUS_WOUNDS, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_DARKVISION, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_INVISIBILITY, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_KEEN_EDGE, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_PROTECTION_FROM_ELEMENTS, oPC, 2);
|
|
AddRunescarSpellChoice(SPELL_CURE_CRITICAL_WOUNDS, oPC, 3);
|
|
AddRunescarSpellChoice(SPELL_DEATH_WARD, oPC, 3);
|
|
AddRunescarSpellChoice(SPELL_DIVINE_POWER, oPC, 3);
|
|
AddRunescarSpellChoice(SPELL_FREEDOM_OF_MOVEMENT, oPC, 3);
|
|
AddRunescarSpellChoice(SPELL_HASTE, oPC, 3);
|
|
AddRunescarSpellChoice(SPELL_GREATER_MAGIC_WEAPON, oPC, 3);
|
|
AddRunescarSpellChoice(SPELL_IMPROVED_INVISIBILITY, oPC, 4);
|
|
AddRunescarSpellChoice(SPELL_NEUTRALIZE_POISON, oPC, 4);
|
|
AddRunescarSpellChoice(SPELL_RESTORATION, oPC, 4);
|
|
AddRunescarSpellChoice(SPELL_RIGHTEOUS_MIGHT, oPC, 4);
|
|
AddRunescarSpellChoice(SPELL_STONESKIN, oPC, 4);
|
|
AddRunescarSpellChoice(SPELL_ANTIMAGIC_FIELD, oPC, 5);
|
|
AddRunescarSpellChoice(SPELL_RUNE_DIMENSION_DOOR, oPC, 5);
|
|
AddRunescarSpellChoice(SPELL_HEAL, oPC, 5);
|
|
AddRunescarSpellChoice(SPELL_POLYMORPH_SELF, oPC, 5);
|
|
AddRunescarSpellChoice(SPELL_SPELL_RESISTANCE, oPC, 5);
|
|
/*
|
|
missing spells
|
|
LEVEL 1 --
|
|
Low-Light Vision,
|
|
LEVEL 3 --
|
|
Air Walk,
|
|
LEVEL 4 --
|
|
Spell Immunity,
|
|
*/
|
|
|
|
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
|
|
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
|
|
}
|
|
else if(nStage == STAGE_LEVEL)
|
|
{
|
|
SetHeader("Which level would you like to scribe this Runescar?");
|
|
int nSpellID = GetLocalInt(oPC, "Runescar_spell");
|
|
int nSpellLevel = GetLocalInt(oPC, "Runescar_spell_level_"+IntToString(nSpellID));
|
|
int nMinLevel = (nSpellLevel*2)-1;
|
|
int i;
|
|
for(i=GetLevelByClass(CLASS_TYPE_RUNESCARRED, oPC);i>=nMinLevel; i--)
|
|
{
|
|
AddChoice("Level "+IntToString(i), i);
|
|
}
|
|
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
|
|
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
|
|
}
|
|
else if(nStage == STAGE_CONFIRM)
|
|
{
|
|
int nSpellID = GetLocalInt(oPC, "Runescar_spell");
|
|
int nLoc = GetLocalInt(oPC, "Runescar_location");
|
|
int nLevel = GetLocalInt(oPC, "Runescar_level");
|
|
int nSpellLevel = GetLocalInt(oPC, "Runescar_spell_level_"+IntToString(nSpellID));
|
|
int nGP = 5*nSpellLevel*nLevel;
|
|
int nXP = nGP/25;
|
|
string sName = GetStringByStrRef(StringToInt(Get2DACache("spells", "Name", nSpellID)));
|
|
string sLoc;
|
|
switch(nLoc)
|
|
{
|
|
case 1: sLoc = "Face"; break;
|
|
case 2: sLoc = "Left Arm"; break;
|
|
case 3: sLoc = "Left Chest"; break;
|
|
case 4: sLoc = "Left Hand"; break;
|
|
case 5: sLoc = "Right Arm"; break;
|
|
case 6: sLoc = "Right Chest"; break;
|
|
case 7: sLoc = "Right Hand"; break;
|
|
}
|
|
string sHeader = "You have selected to scribe "+sName+" on your "+sLoc+" at level "+IntToString(nLevel)+".\n";
|
|
sHeader += "This will cost "+IntToString(nGP)+"gp and "+IntToString(nXP)+"xp.\n";
|
|
sHeader += "You will take "+IntToString(nSpellLevel)+"d6 damage.\n";
|
|
sHeader += "Is this correct?";
|
|
int nHitDiceXP = (500 * GetHitDice(oPC) * (GetHitDice(oPC) - 1));
|
|
if(GetGold(oPC) < nGP)
|
|
{
|
|
if((GetXP(oPC)-nHitDiceXP)<nXP)
|
|
AddChoice("Insufficient gold and experience", 0);
|
|
else
|
|
AddChoice("Insufficient gold", 0);
|
|
}
|
|
else if((GetXP(oPC)-nHitDiceXP)<nXP)
|
|
AddChoice("Insufficient experience", 0);
|
|
else
|
|
{
|
|
AddChoice("Yes", 1);
|
|
AddChoice("No", 0);
|
|
}
|
|
SetHeader(sHeader);
|
|
MarkStageSetUp(nStage, oPC); // This prevents the setup being run for this stage again until MarkStageNotSetUp is called for it
|
|
SetDefaultTokens(); // Set the next, previous, exit and wait tokens to default values
|
|
}
|
|
}
|
|
|
|
// Do token setup
|
|
SetupTokens();
|
|
}
|
|
// End of conversation cleanup
|
|
else if(nValue == DYNCONV_EXITED)
|
|
{
|
|
// Add any locals set through this conversation
|
|
DeleteLocalInt(oPC, "Runescar_location");
|
|
DeleteLocalInt(oPC, "Runescar_spell");
|
|
DeleteLocalInt(oPC, "Runescar_level");
|
|
}
|
|
// Abort conversation cleanup.
|
|
// NOTE: This section is only run when the conversation is aborted
|
|
// while aborting is allowed. When it isn't, the dynconvo infrastructure
|
|
// handles restoring the conversation in a transparent manner
|
|
else if(nValue == DYNCONV_ABORTED)
|
|
{
|
|
// Add any locals set through this conversation
|
|
DeleteLocalInt(oPC, "Runescar_location");
|
|
DeleteLocalInt(oPC, "Runescar_spell");
|
|
DeleteLocalInt(oPC, "Runescar_level");
|
|
}
|
|
// Handle PC responses
|
|
else
|
|
{
|
|
// variable named nChoice is the value of the player's choice as stored when building the choice list
|
|
// variable named nStage determines the current conversation node
|
|
int nChoice = GetChoice(oPC);
|
|
if(nStage == STAGE_ENTRY)
|
|
{
|
|
SetLocalInt(oPC, "Runescar_location", nChoice);
|
|
nStage = STAGE_SPELL;
|
|
}
|
|
else if(nStage == STAGE_SPELL)
|
|
{
|
|
SetLocalInt(oPC, "Runescar_spell", nChoice);
|
|
nStage = STAGE_LEVEL;
|
|
}
|
|
else if(nStage == STAGE_LEVEL)
|
|
{
|
|
SetLocalInt(oPC, "Runescar_level", nChoice);
|
|
nStage = STAGE_CONFIRM;
|
|
}
|
|
else if(nStage == STAGE_CONFIRM)
|
|
{
|
|
if(nChoice)
|
|
{
|
|
int nSpellID = GetLocalInt(oPC, "Runescar_spell");
|
|
int nLoc = GetLocalInt(oPC, "Runescar_location");
|
|
int nLevel = GetLocalInt(oPC, "Runescar_level");
|
|
int nSpellLevel = GetLocalInt(oPC, "Runescar_spell_level_"+IntToString(nSpellID));
|
|
int nGP = 5*nSpellLevel*nLevel;
|
|
int nXP = nGP/25;
|
|
//remove GP & XP
|
|
SetXP(oPC, GetXP(oPC)-nXP);
|
|
TakeGoldFromCreature(nGP, oPC, TRUE);
|
|
//do damage
|
|
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(d6(nSpellLevel)), oPC);
|
|
//mark the scar
|
|
string sVar;
|
|
switch(nLoc)
|
|
{
|
|
case 1: sVar = "Runescar_Face"; break;
|
|
case 2: sVar = "Runescar_Arm_Left"; break;
|
|
case 3: sVar = "Runescar_Chest_Left"; break;
|
|
case 4: sVar = "Runescar_Hand_Left"; break;
|
|
case 5: sVar = "Runescar_Arm_Right"; break;
|
|
case 6: sVar = "Runescar_Chest_Right"; break;
|
|
case 7: sVar = "Runescar_Hand_Right"; break;
|
|
}
|
|
//+1 for 0 == null to work
|
|
SetPersistantLocalInt(oPC, sVar, nSpellID+1);
|
|
SetPersistantLocalInt(oPC, sVar+"_level", nLevel);
|
|
//use a useage
|
|
SetLocalInt(oPC, "Runescar_slot_"+IntToString(nSpellLevel),
|
|
GetLocalInt(oPC, "Runescar_slot_"+IntToString(nSpellLevel))-1);
|
|
}
|
|
MarkStageNotSetUp(STAGE_ENTRY, oPC);
|
|
MarkStageNotSetUp(STAGE_SPELL, oPC);
|
|
MarkStageNotSetUp(STAGE_LEVEL, oPC);
|
|
MarkStageNotSetUp(STAGE_CONFIRM, oPC);
|
|
nStage = STAGE_ENTRY;
|
|
}
|
|
|
|
// Store the stage value. If it has been changed, this clears out the choices
|
|
SetStage(nStage, oPC);
|
|
}
|
|
}
|