PRC8/nwn/nwnprc/trunk/spells/prc_scry_conv.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

253 lines
9.3 KiB
Plaintext

//:://////////////////////////////////////////////
//:: Scry Conversation
//:: prc_scry_conv
//:://////////////////////////////////////////////
/** @file
This lets you choose which creature or PC to target
@author Stratovarius
@date Created - 30.04.2007
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "prc_alterations"
#include "inc_dynconv"
#include "prc_inc_scry"
//////////////////////////////////////////////////
/* Constant defintions */
//////////////////////////////////////////////////
const int STAGE_CHOOSE_TARGET = 0;
const int STAGE_CONFIRMATION = 1;
//////////////////////////////////////////////////
/* Aid functions */
//////////////////////////////////////////////////
void StorePCForRecovery(object oPC, object oChoice, int nChoice)
{
SetLocalObject(oPC, "ScryTarget" + IntToString(nChoice), oChoice);
}
object RetrievePC(object oPC, int nChoice)
{
return GetLocalObject(oPC, "ScryTarget" + IntToString(nChoice));
}
void AddLegalTargets(object oPC)
{
// This reads all of the legal choices
int nSpellId = GetLocalInt(oPC, "ScrySpellId");
int nChoice = 1;
if (nSpellId == SPELL_LOCATE_OBJECT)
{
// First, get all objects in the area you're in
object oObject = GetFirstObjectInArea(GetArea(oPC));
while (GetIsObjectValid(oObject) == TRUE)
{
if(DEBUG) DoDebug("prc_scry_conv: Looping Object Targets");
// Don't target PCs using this
if (GetObjectType(oObject) == OBJECT_TYPE_PLACEABLE || GetObjectType(oObject) == OBJECT_TYPE_ITEM)
{
// If its a legal object, target it for locating
AddChoice(GetName(oObject), nChoice, oPC);
StorePCForRecovery(oPC, oObject, nChoice);
}
nChoice += 1;
oObject = GetNextObjectInArea(GetArea(oPC));
}
}
else
{
// First, get all creatures in the area you're in
object oCreature = GetFirstObjectInArea(GetArea(oPC));
while (GetIsObjectValid(oCreature) == TRUE)
{
if(DEBUG) DoDebug("prc_scry_conv: Looping Monster Targets");
// Don't target PCs using this
if (GetObjectType(oCreature) == OBJECT_TYPE_CREATURE)
{
// This can target PCs in the area, but not in other areas
if ((nSpellId == SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE ||
nSpellId == SPELL_LOCATE_CREATURE ||
nSpellId == MYST_TRAIL_OF_HAZE ||
nSpellId == POWER_CLAIRVOYANT_SENSE) &&
oPC != oCreature &&
!GetIsDM(oCreature))
{
AddChoice(GetName(oCreature), nChoice, oPC);
StorePCForRecovery(oPC, oCreature, nChoice);
}
// Normally, the second part takes care of all PCs
else if ((!GetIsPC(oCreature) && !GetIsDM(oCreature)))
{
AddChoice(GetName(oCreature), nChoice, oPC);
StorePCForRecovery(oPC, oCreature, nChoice);
}
}
nChoice += 1;
oCreature = GetNextObjectInArea(GetArea(oPC));
}
// These only target in their own areas
if (nSpellId != SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE &&
nSpellId != SPELL_LOCATE_CREATURE &&
nSpellId != MYST_TRAIL_OF_HAZE &&
nSpellId != POWER_CLAIRVOYANT_SENSE)
{
// Now, loop through all of the PCs
object oPCTarget = GetFirstPC();
// Don't target yourself
while (GetIsObjectValid(oPCTarget))
{
if(oPCTarget != oPC && !GetIsDM(oPCTarget))
{
if(DEBUG) DoDebug("prc_scry_conv: Looping PC Targets");
AddChoice(GetName(oPCTarget), nChoice, oPC);
StorePCForRecovery(oPC, oPCTarget, nChoice);
nChoice += 1;
}
oPCTarget = GetNextPC();
}
}
}
}
//////////////////////////////////////////////////
/* 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))
{
// variable named nStage determines the current conversation node
// Function SetHeader to set the text displayed to the PC
// Function AddChoice to add a response option for the PC. The responses are show in order added
if(nStage == STAGE_CHOOSE_TARGET)
{
// Set the header
string sAmount = "Which creature would you like to scry?";
SetHeader(sAmount);
AddLegalTargets(oPC);
MarkStageSetUp(STAGE_CHOOSE_TARGET, 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_CONFIRMATION)//confirmation
{
object oChoice = RetrievePC(oPC, GetLocalInt(oPC, "ScryChoice"));
AddChoice(GetStringByStrRef(4752), TRUE); // "Yes"
AddChoice(GetStringByStrRef(4753), FALSE); // "No"
string sText = "You have selected " + GetName(oChoice) + " as the creature to scry.\n";
sText += "Is this correct?";
SetHeader(sText);
MarkStageSetUp(STAGE_CONFIRMATION, oPC);
}
}
// Do token setup
SetupTokens();
}
// End of conversation cleanup
else if(nValue == DYNCONV_EXITED)
{
// End of conversation cleanup
DeleteLocalObject(oPC, "ScryTarget" + IntToString(GetLocalInt(oPC, "ScryChoice")));
DeleteLocalInt(oPC, "ScryChoice");
}
// 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)
{
// End of conversation cleanup
DeleteLocalObject(oPC, "ScryTarget" + IntToString(GetLocalInt(oPC, "ScryChoice")));
DeleteLocalInt(oPC, "ScryChoice");
}
// 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_CHOOSE_TARGET)
{
SetLocalInt(oPC, "ScryChoice", nChoice);
nStage = STAGE_CONFIRMATION;
}
else if(nStage == STAGE_CONFIRMATION)//confirmation
{
// Scry and Exit
if(nChoice == TRUE)
{
object oChoice = RetrievePC(oPC, GetLocalInt(oPC, "ScryChoice"));
// This is only used by See the Named, otherwise it should fail to fire.
if(GetLocalInt(oPC, "SeeTheNamed"))
{
int nDC = 15 + (2 * FloatToInt(GetChallengeRating(oChoice)));
if (GetIsSkillSuccessful(oPC, SKILL_TRUESPEAK, nDC))
{ // The function will take it from here
ScryMain(oPC, oChoice);
}
else // Clean up effects
{
PRCRemoveSpellEffects(TRUE_SEE_THE_NAMED, oPC, oPC);
}
}
else
{
// The function will take it from here
ScryMain(oPC, oChoice);
}
// And we're all done
AllowExit(DYNCONV_EXIT_FORCE_EXIT);
}
else
{
nStage = STAGE_CHOOSE_TARGET;
MarkStageNotSetUp(STAGE_CHOOSE_TARGET, oPC);
MarkStageNotSetUp(STAGE_CONFIRMATION, oPC);
}
DeleteLocalObject(oPC, "ScryTarget" + IntToString(GetLocalInt(oPC, "ScryChoice")));
DeleteLocalInt(oPC, "ScryChoice");
}
// Store the stage value. If it has been changed, this clears out the choices
SetStage(nStage, oPC);
}
}