Making Quests To Include all Party Members
This scripting forum is to discuss scripting and for those needing help scripting to get help from others.

Moderators: Mermut, rdjparadis

Post Reply
User avatar
Winterhawk99
Posts: 1627
Joined: Thu Oct 08, 2009 12:00 am
ctp: Yes
nwnihof: Yes
Location: Pa.
Contact:

Making Quests To Include all Party Members

Post by Winterhawk99 »

This one will be a boon for all the folk that build quests for PWs. The Lexicon and other recourses teach how to build quests for single player modules. Most do not teach how to build a quest for Persistent worlds where you may have a dozen people in a party all participating in the quest that they are on. For this one I'm going to use two scripts.

The first will by for parties in a game with no outside database. I'm not sure if beamdog included for a way to put integers on character PCs. I must assume that they have not. In the original game you could not put them directly on PCs and have them stick to the toon once they logged off or the game went down. If you have a SQL or Linux database keeping track of things you can place the integers on PCs every time they come into the game so theres two different ways to do this. The second script will be for those that do have outside DBs and can track ints. on toons.


The script here will carry all party members through a quest if you used the basics of the script iteself:

Code: Select all

//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
//:: Created By: Winterhawk99
//:: Created On: 12/28/2018 1:11 am
//:://////////////////////////////////////////////
void main()
{
    object oPC = GetPCSpeaker();
    string sQuest = "06_SpinQuest";
    int iState = 25;

    object oPal = GetFirstFactionMember(oPC);
    while (GetIsObjectValid(oPal))
    {
        if (GetArea(oPal) == GetArea(oPC) && GetLocalInt(oPal, sQuest) == 0)
        {
            SetLocalInt(oPal, sQuest, iState);
            AddJournalQuestEntry(sQuest, iState, oPal, FALSE);
        }
        oPal = GetNextFactionMember(oPC);
    }

}

The first thing you see here is that we are defining variables so we can use them in the main body of the script. They are:
object oPC = GetPCSpeaker(); This is the PC speaking to the NPC quest giver
object oPal = GetFirstFactionMember(oPC); Every other PC in the first PCs party including speaker first
int iState = 25; This is the integer we will be putting on two different things
string sQuest = "06_SpinQuest"; This is both the name of the tracking integer for the quest and
The tag of the journal quest entry


If I use the the name of the tracking integer as the Journal tag it takes 1/2 the scripting to do what I want to get done. You just have to remember to use the same numbers in each individual journal entry as you track the integer. change the interger then if a journal entry is needed you to to the journal editor and do that. This also handles all journal entries completely in script so you dont have to mess with journal entries in the conversational editor. All you have to do is fill out the journal and mark it finished on completion of the quest.

while (GetIsObjectValid(oPal))


This tells the engine to cycle through every party member starting with the pc speaking and do everthing In the parameters to each individual in the party as long as they are in the same area.

if (GetArea(oPal) == GetArea(oPC) && GetLocalInt(oPal, sQuest) == 0)


This makes sure its only putting the integer on the PCs in the same area and that none of the PCs are already doing the quest.

SetLocalInt(oPal, sQuest, iState);
AddJournalQuestEntry(sQuest, iState, oPal, FALSE);


this is the meat of the script. It sets the tracking integer on each PC and then Adds the journal entry to each PC.

oPal = GetNextFactionMember(oPC);


This last statement sets up the loop to go to each pc and do it again until there are no more party members to put a number on. Its saying ok I have done the first pc go to the next pc.


If you use this technique A party of people can do the whole quest and all will recieve rewards.

Now for those that do have data bases it is much the same except the party can break up mid quest and leave and each individual PC can come back to the server at different times and complete the quest on their own if they want too. Its not too much different from what is above:

Code: Select all

//::///////////////////////////////////////////////
//:: Name hgdw_set1
//:://////////////////////////////////////////////
/*
    Hungry Dwarves Quest, set 1, PC accepted quest

    Set state on all elligible party
        members in the area
*/
//:://////////////////////////////////////////////
//:: Created By: Mermut
//:: Created On: March 12, 2008
//:://////////////////////////////////////////////
#include "aps_include"

void main()
{
    object oPC = GetPCSpeaker();
    string sQuest = "06_Dwarfquest";
    int iState = 1;

    object oPal = GetFirstFactionMember(oPC);
    while (GetIsObjectValid(oPal))
    {
        if (GetArea(oPal) == GetArea(oPC) && GetPersistentInt(oPal, sQuest) == 0)
        {
            SetPersistentInt(oPal, sQuest, iState);
            AddJournalQuestEntry(sQuest, iState, oPal, FALSE);
        }
        oPal = GetNextFactionMember(oPC);
    {
{

As you can see there isn't much difference between the first and the second. Lets go over what is different.

First you have an include

#include "aps_include"

Those of us that have outside databases know that this is the working include for an SQL database that can hold any variable (except arrays that NWN doesn't use) You wand to put in the game. I also used mine for my random treasure tables. So You can also put and call up items or placeables from a database too.

GetPersistentInt(oPal, sQuest) == 0)

This is calling the integer from the database instead of the game whenever you see persistent It means the information is not in the game its in the SQL database inventory

SetPersistentInt(oPal, sQuest, iState);

This line changes the integer to iState (1) and telling the engine to store it in the SQL database under the name of the PC. Notice that persistent is not on the journal entry line. That is because the journal is in the game and putting it outside doesnt do anthing because journal entries have no load on the engine itself.
CTP team member
http://www.harvestmoonconsortium.com
Chief cook and bottle washer for Harvest Moon

Post Reply