Persistent Quest System
Posted: Tue Aug 14, 2007 4:46 am
AL has found some holes in my quest system that I'd like help ironing out with the goal of releasing it (or another version someone else has got) for use by all builders.
I'll put the version for a simple bounty quest as an example.
NPC: Kill Jubilex and I'll give you a reward.
Text Appears When: Quest_Progress (the NPC checks all party members and only offers the quest if)
Variables:
string sQuest = Kill_Jubilex
NOT int nState = 3
Actions Taken: Quest_Start
Variables:
string sQuest = Kill_Jubilex
int nState = 1
Trigger OnEnter: Quest_Trigger_Encounter
Variables:
sQuest = Kill Jubilex, nGoal = 1, sObjectType = C, sTemplate = Jubilex, sLocationTag = wp_jubilex, bUseAppearAnimation = 1, fDelay = 3, nSpawn = 1, nDoOnce = kill_jubilex
NPC: Kill Jubilex?
Text Appears When: Quest_Progress (the NPC checks all party members and only rewards the quest if)
Variables:
string sQuest = Kill_Jubilex
int nState = 2
When rewarding the party, Kill_Jubilex is bumped to 3 on all party members.
Actions Taken: Quest_Finish
Variables:
string sQuest = Kill_Jubilex
int nState = 3
But AL's found some holes in it and I could use help sorting them out. It may be an ass-about way of doing things, so suggest alternatives at will.
I'll put the version for a simple bounty quest as an example.
NPC: Kill Jubilex and I'll give you a reward.
Text Appears When: Quest_Progress (the NPC checks all party members and only offers the quest if)
Variables:
string sQuest = Kill_Jubilex
NOT int nState = 3
PC: Accept#include "qst__pqj_nwnx_inc"
int StartingConditional(string sQuest, int nState)
{
object oCreature = GetPCSpeaker();
if(RetrieveQuestState(sQuest, GetPCSpeaker()) == nState)
return TRUE;
else
return FALSE;
}
Actions Taken: Quest_Start
Variables:
string sQuest = Kill_Jubilex
int nState = 1
PC seeks Jubilex and enters a trigger at the front door of his lair, spawning Jubilex only if they have the quest. The trigger is set up as follows:#include "qst__pqj_nwnx_inc"
void main(string sQuest, int nState)
{
object oPCMember=GetPCSpeaker();
if (!GetIsObjectValid(oPCMember))
oPCMember=GetFirstPC();
object oPCF = GetFirstFactionMember(oPCMember,FALSE);
while (GetIsObjectValid(oPCF))
{
AddPersistentJournalQuestEntry(sQuest, nState, oPCF, TRUE);
oPCF = GetNextFactionMember(oPCMember, TRUE);
}
}
Trigger OnEnter: Quest_Trigger_Encounter
Variables:
sQuest = Kill Jubilex, nGoal = 1, sObjectType = C, sTemplate = Jubilex, sLocationTag = wp_jubilex, bUseAppearAnimation = 1, fDelay = 3, nSpawn = 1, nDoOnce = kill_jubilex
You kill Jubilex, nState is bumped to 2, and return to NPC.#include "qst__pqj_nwnx_inc"
#include "ginc_var_ops"
#include "ginc_actions"
void main()
{
object oPC = GetEnteringObject();
string sTemplate = GetLocalString(OBJECT_SELF, "sTemplate");
string sLocationTag = GetLocalString(OBJECT_SELF, "sLocationTag");
int bUseAppearAnimation = GetLocalInt(OBJECT_SELF, "bUseAppearAnimation");
string sNewTag = GetLocalString(OBJECT_SELF, "sNewTag");
float fDelay = GetLocalFloat(OBJECT_SELF, "fDelay");
string sQuest = GetLocalString(OBJECT_SELF, "sQuest");
int nState = RetrieveQuestState(sQuest, oPC);
int nSpawn = GetLocalInt(OBJECT_SELF, "nSpawn");
int nGoal = GetLocalInt(OBJECT_SELF, "nGoal");
object oTarget;
object oSpawn;
location lTarget;
oTarget = GetNearestObjectByTag(sLocationTag);
if (GetIsPC(oPC))
{
if (RetrieveQuestState(sQuest, oPC)>= nSpawn)
if (RetrieveQuestState(sQuest, oPC)<nGoal>= 1)
if (RetrieveQuestState(sQuest, oPC)<= nGoal)
{
SetLocalIntOnAll(oPC, sQuest, nState);
FloatingTextStringOnCreature(sFloatingText, oPC);
AddPersistentJournalQuestEntry(sQuest, nState, oPC, TRUE);
}
}
}
NPC: Kill Jubilex?
Text Appears When: Quest_Progress (the NPC checks all party members and only rewards the quest if)
Variables:
string sQuest = Kill_Jubilex
int nState = 2
When rewarding the party, Kill_Jubilex is bumped to 3 on all party members.
Actions Taken: Quest_Finish
Variables:
string sQuest = Kill_Jubilex
int nState = 3
The obvious advatage of this system is that it requires no scripting and consists of 5 template scripts. You get a template conversation, template trigger and template mob, and all the builder has to do is fill in variable names and values and add journal entries.#include "acr_xp_i"
#include "qst__pqj_nwnx_inc"
void main(string sQuest, int nState)
{
if (GetLocalInt(GetModule(),sQuest)<nState)
SetLocalInt(GetModule(),sQuest,nState);
if ((GetGlobalInt(sQuest)<nState))
SetGlobalInt(sQuest,nState);
object oPCMember=GetPCSpeaker();
if (!GetIsObjectValid(oPCMember))
oPCMember=GetFirstPC();
object oPCF = GetFirstFactionMember(oPCMember,FALSE);
while (GetIsObjectValid(oPCF))
{
AddPersistentJournalQuestEntry(sQuest, nState, oPCF, TRUE);
ACR_GiveXPToPC(oPCF, GetJournalQuestExperience(sQuest));
oPCF = GetNextFactionMember(oPCMember, TRUE);
}
}
But AL's found some holes in it and I could use help sorting them out. It may be an ass-about way of doing things, so suggest alternatives at will.