Aller au contenu

Photo

Script Idea - packing a crate


  • Veuillez vous connecter pour répondre
29 réponses à ce sujet

#1
Friar

Friar
  • Members
  • 293 messages
If I wanted to create a quest that asks the PC to load a crate and get paid, then how should I go about it?

So far I have the PC talk to the NPC.
- NPC conversation spawns a sack 'placeable' on a random pallet "waypoint" when player says something like "Ready to get to work."
- PC uses the sack 'placeable' and the sack 'placeable' disappears.
- A sack 'item' now appears in the PC's inventory.
- PC puts sack 'item' in crate 'placeable container'

That is what happens so far, but what must happen next is:
- Crate 'placeable container' counts sack 'items' in it's own inventory.
- When (5) sack 'items' are in the inventory of the crate placeable container the quest is completed.

Miscellaneous Things:
- Sack 'item' weight needs to be about 50 lbs. and I can't seem to find how to adjust the weight.

#2
Tchos

Tchos
  • Members
  • 5 042 messages
The weight of an item is determined by its base type, and their weights are set in the baseitems.2da. If there's no item in there that has the weight you want and doesn't turn it into a wearable item or crafting item or something else you don't want it to do, then you'll have to add a custom entry to baseitems.2da.

Or, you can add a property to it that increases its weight in the toolset, under Item Properties.  (Edit: No, you can only reduce the weight there.)

For the crate, make a script to put in its "On Inventory Disturbed" slot (or On Closed), so it'll count up the necessary item when the player closes it.

I think it may need to be in On Closed, not Disturbed, because when I did a similar thing, I put it in the On Closed slot.  Mine looks for separate, uniquely-tagged items, though, so it's not quite what you're wanting.

Modifié par Tchos, 14 janvier 2014 - 04:22 .


#3
Friar

Friar
  • Members
  • 293 messages
Thanks again Tchos,

I'm thinking the On Closed script might be the best route now that you mentioned it.
Here's what I have so far:

//Put this script OnClose
void main()
{

object oPC = GetLastClosedBy();

if (!GetIsPC(oPC)) return;

if (GetItemPossessedBy(oPC, "warehouse_goods1")!= OBJECT_INVALID)
   {
   oTarget = GetObjectByTag("warehouse_goods1");
//What should I do to get the 'check for item' to happen on the placeable crate container and not the PC? What is the command for quantity?
   DestroyObject(oTarget, 0.0);

   AddJournalQuestEntry("The Quest", 1, oPC, TRUE, FALSE);

   }
}

#4
kevL

kevL
  • Members
  • 4 056 messages
// Put this script OnClose
// - relies on "warehouse_goods" (items in crate) all having the same Tag.

void main()
{
    int iTotal = 0;

    object oGoods = GetFirstItemInInventory();
    while (GetIsObjectValid(oGoods))
    {
        // count how many Goods are in the crate
        if (GetTag(oGoods) == "warehouse_goods")
            iTotal++;

        if (iTotal == 5)
            break;
        oGoods = GetNextItemInInventory();
    }

    // if the quota is met
    if (iTotal == 5)
    {
        object oPC = GetLastClosedBy();
        if (!GetIsPC(oPC))
            return;

        AddJournalQuestEntry("the_warehouse_goods_quest", 1, oPC);

        iTotal = 0;

        oGoods = GetFirstItemInInventory();
        while (GetIsObjectValid(oGoods)
                && iTotal <= 5)
        {
            // don't destroy more than 5 Goods per onClose
            if (GetTag(oGoods) == "warehouse_goods")
                DestroyObject(oGoods);

            iTotal++;
            oGoods = GetNextItemInInventory();
        }
    }
}


sorta like that?

Modifié par kevL, 14 janvier 2014 - 09:00 .


#5
kevL

kevL
  • Members
  • 4 056 messages
note: the items might have to reiterate from FirstItem after DestroyObject()

...

#6
Tchos

Tchos
  • Members
  • 5 042 messages

koundog1 wrote...
//What should I do to get the 'check for item' to happen on the placeable crate container and not the PC?

Just for future reference, since kevL took care of the script, but if you put a script in an object's script slot, like On Closed, then you can refer to that object with OBJECT_SELF.  So just replace oPC with OBJECT_SELF.

#7
Friar

Friar
  • Members
  • 293 messages
Thanks a lot guys,
I am learning so much about scripting and it is really really appreciated.

EDIT:
Since you guys are so knowledgeable and you've been so helpful I might add to this question.

I've created a conversation, for the quest giver (NPC_2), which has (5) possible NPC intro stems from the conversation root.

- Each stem should give you the quest of loading the crates with (5) items; previously mentioned.

- Each completion will allow you to talk to NPC_1 and be paid 1 or 2 gold depending on whether you successfully rolled on the appraise skill after talking to him earlier.

- Each completion will allow the PC to proceed to the next stem in the conversation.

- By the fourth stem the PC will have done enough of loading crates. He will have also learned some valuable information from the other workers and finally, he will have earned the respect of everyone in the warehouse thus allowing him to proceed should he desire.

- The story can go on and he can meet the contact that NPC_2 will tell him about or NPC_1 will offer other side jobs.

- By the fifth conversation stem the PC can work as many times in the warehouse as his little heart desires for the pitance of 1 or 2 gp...

no hope for a raise... no hope of ever going on a fantastic adventure... oh gee sorry we aren't talking about my personal problems here are we? lol!

- Bottom line is that the quest should be repeatable, but that the first four conversations will have all of the interesting particulars. For that reason I'm wondering if going the quest journal route is the best option. I'm trying to become more acquainted with variables or coins or whatever they are called. But before I delve into it I thought maybe you guys might have some more useful suggestions.

Modifié par koundog1, 15 janvier 2014 - 04:41 .


#8
Tchos

Tchos
  • Members
  • 5 042 messages
I like to use the journal to keep track of as much as possible, just to keep things neat and organised in one place. There are pros and cons in using variables to keep track of this or that, but I think for this particular instance, I'd just make 5 journal entries that have the same text if you want it to always look the same, or which gradually add the tantalising info you mention learning, which I think would be better. Those entries would be what control the conversation node.

#9
kevL

kevL
  • Members
  • 4 056 messages
sounds like a perfect job for using the Journal to keep track of. Aye

I'd tend to go with whatever's easiest, in my mind, to use. ie, the syntax for GetLocalInt/SetLocalInt, gc_local_int/ga_local_int are etched up there (here). But Tchos has been a big proponent of using the journal and i'd, err, have to look it up but it strikes me as a really good method if&as applicable! For example, when using locals, where do ya put them? on the Crate, on the Area, on the Module, use a global??? On the other hand, you always know where the journal entry is.

But sometimes all ya needs a local... SetLocalInt(OBJECT_SELF, "Done", TRUE); ( not in your case here tho )

Personally I'd have to look more into the two scripts, ga_journal & gc_journal, before using the method. That is, i notice that gc_journal simply uses local_ints on the PC, with a varname that starts with "NW_JOURNAL_ENTRY", +sQuestTag appended. But does ga_journal actually write a local? not that i see.... a test is in order there before i'd stamp it Reliable. Ofc a fella can write their own gc/ga scripts but, everything has a butt except 1==TRUE and 0==FALSE

although NwN2 has even pushed my boundaries on that,


/shrugzorz


ps. coins? I think you mean tokens, related to locals but not quite.

#10
Tchos

Tchos
  • Members
  • 5 042 messages

kevL wrote...
Personally I'd have to look more into the two scripts, ga_journal & gc_journal, before using the method. That is, i notice that gc_journal simply uses local_ints on the PC, with a varname that starts with "NW_JOURNAL_ENTRY", +sQuestTag appended. But does ga_journal actually write a local? not that i see.... a test is in order there before i'd stamp it Reliable.

I can't know for certain, but without further information one way or the other, my conjecture is that the hard-coded function works the same way as gc_journal does it, and is the same way the journal was handled in NWN1, but with the hard-coded function AddJournalQuestEntry() you just can't see what it's doing.  The main evidence is that you can use one method to set the journal entry, and it still works if you use the other method to check it.  In other words, yes, the journal's current status is handled with local variables on the PC.  But I'd welcome more testing to confirm that.

The important thing is to ensure the ga_ function is set to update the journal on all PCs, or else you can have inconsistent results if you start a conversation with a party member other than the main PC.  That's one of the reasons that I wrote replacement ga_ and gc_ scripts for my campaign which always set the journal entries on the First PC.

The thing that sets the journal apart from any other local ints is that it gives you a built-in, easily accessible spreadsheet that allows extensive commenting and description, so you know exactly what the different integers (the quest stages) mean.

#11
Tchos

Tchos
  • Members
  • 5 042 messages
BTW, as an example of how I use both the journal and my conversations, I've settled on the method of prefacing each entry with a comment for myself {in curly braces}, which as you may know don't display in-game. So I start by creating branches for all possible conditions, described in my comments, and then write the dialogue trees for those situations. Something like this -- these are conversation starting nodes, with the numbers referring to journal entry conditions:

{0 or 10: PC is not on the quest, or got the quest from X and has not found any [quest item]s yet}
----{10: PC got quest from X}
---------{Set quest to 20}
----{Some other things}
---------{Set quest to 20}
{15: PC found some [quest item]s, but had never talked to X and thus was not yet on the quest}
----{Set quest to 20}
{20: PC was sent by Y to find her [quest item]s, but doesn't have them all yet, and may not have any of them}
{25: PC found all items before talking to Y}
----{SET QUEST TO 40}
{30: PC was sent by Y to find her [quest item]s, and has them all.}
----{SET QUEST TO 40}
{>30: Y's part in the quest is finished, but she has not yet [left].}

I obscured some of the details to avoid spoilers. I also left out the actual dialogue and most side branches, to show just the skeleton of the conversation based purely on the journal. There are other ways of checking things, such as actually checking your inventory to see if you have items, but I set this up in such a way that finding the items updates the journal.

There are other conversation structures, such as the fall-through method, and I used that for my earlier conversations, but I like this method better.

#12
Lugaid of the Red Stripes

Lugaid of the Red Stripes
  • Members
  • 955 messages

Tchos wrote...
The thing that sets the journal apart from any other local ints is that it gives you a built-in, easily accessible spreadsheet that allows extensive commenting and description, so you know exactly what the different integers (the quest stages) mean.


Furthermore, it's avaible for the player to look at right in the journal gui.  I've actually started prefacing my journal entries with the state number, just so I know exactly where the player is in the quest when they report a bug. 
ga_journal is also easily used from the console to update journal entries, while ga_localint needs a more specific pointer to the object with the local int.

#13
kevL

kevL
  • Members
  • 4 056 messages
sounds good.

My guess, too, is it's hardcoded. The only other reference i find to "NW_JOURNAL_ENTRY" is in ginc_journal:

int GetJournalQuestEntry(string sPlotID, object oCreature)
{
  int iQuestEntry = GetLocalInt(oCreature, "NW_JOURNAL_ENTRY" + sPlotID);
  return iQuestEntry;
}


( for those times when PC isn't in dialog as GetPCSpeaker )

btw, just noting the 2 dialog scripts are
- ga_journal
- gc_journal_entry


and, in case koundog's wondering: 0==FALSE, anything other than 0 is TRUE...

(except in NwN2 where half a function is hardcoded and the other half isnt :P

Modifié par kevL, 15 janvier 2014 - 08:39 .


#14
Friar

Friar
  • Members
  • 293 messages
// Put this script OnClose
// - relies on "warehouse_goods" (items in crate) all having the same Tag.

void main()
{
    int iTotal = 0;

    object oGoods = GetFirstItemInInventory();
    while (GetIsObjectValid(oGoods))
    {
        // count how many Goods are in the crate
        if (GetTag(oGoods) == "warehouse_goods")
            iTotal++;

        if (iTotal == 5)
            break;
        oGoods = GetNextItemInInventory();
    }

    // if the quota is met
    if (iTotal == 5)
    {
        object oPC = GetLastClosedBy();
        if (!GetIsPC(oPC))
            return;

        AddJournalQuestEntry("the_warehouse_goods_quest", 1, oPC);

        iTotal = 0;

        oGoods = GetFirstItemInInventory();
        while (GetIsObjectValid(oGoods)
                && iTotal <= 5)
        {
            // don't destroy more than 5 Goods per onClose
            if (GetTag(oGoods) == "warehouse_goods")
                DestroyObject(oGoods);

            iTotal++;
            oGoods = GetNextItemInInventory();
        }
    }
}

sorta like that?

 

 

I'm happy with this script. Thanks KevL!

 

It logs how many objects I put in a container and then the quest updates.

 

The issue I'm running into now is that I need the script to update more journal entries, but I do not know how to make it distinguish which entry it should update.

Right now it only updates

 

AddJournalQuestEntry("job_laborer1", 21, oPC);

 

I need it to update several other journal entries.

 

AddJournalQuestEntry("job_laborer1", 21, oPC);

AddJournalQuestEntry("job_laborer1", 61, oPC);

AddJournalQuestEntry("job_laborer1", 101, oPC);

AddJournalQuestEntry("job_laborer1", 141, oPC);

AddJournalQuestEntry("job_laborer1", 181, oPC);

 

It also needs to update these quests if the player successfully roled on the appraise skill and is paid 2 gp after completion.

AddJournalQuestEntry("job_laborer2", 21, oPC);

AddJournalQuestEntry("job_laborer2", 61, oPC);

AddJournalQuestEntry("job_laborer2", 101, oPC);

AddJournalQuestEntry("job_laborer2", 141, oPC);

AddJournalQuestEntry("job_laborer2", 181, oPC);

 

So as the player finishes each quest they can ask to do it again. To the player it looks like they are grinding until they get to entries 141 and 181.

By that time the NPCs will explain they earned everyone's respect and they know of an opportunity that might be more profitable.

 

Quest 181 can continue to loop and the player can grind out 1 to 2 gp to their litle hearts desire. But with the appropriate journal entry finished new dialogue options appear and they can move on if they want.

 

So if journal entry 21 is completed then the script should check and then if yes then update to entry 61.

if journal entry 61 is completed then update to 101

if 101 is then update to 141

if 141 then 181

If 181 then reset 181?

 

I hope this makes sense.



#15
kevL

kevL
  • Members
  • 4 056 messages
Try this out, but i warn you I don't quite understand what you're getting at w/ the two journal threads.

[edit] k, this ought work better
 
// Put this script OnClose
// - relies on "warehouse_goods" (items in crate) all having the same Tag.
// - assumes PC can have only one of the two related quests.

void main()
{
    object oPC = GetLastClosedBy();
    if (!GetIsPC(oPC))
        return;

    int bLabor = 0;

    int iState = GetJournalEntry("job_laborer1", oPC);
    if (!iState)
    {
        bLabor = 1;
        iState = GetJournalEntry("job_laborer2", oPC);
    }

    if (!iState)
        return;

    switch (iState)
    {
        case 1:
        case 41:
        case 81:
        case 121:
        case 161:
            SendMessageToPC(oPC, "Talk to the foreman for instructions.");
        return;

        case 21:
        case 61:
        case 101:
        case 141:
        case 181:
            SendMessageToPC(oPC, "Talk to the clerk to get paid.");
        return;

        case 31:
        case 71:
        case 111:
        case 151:
        case 191:
            SendMessageToPC(oPC, "Talk to the clerk for instructions.");
        return;
    }


    int iTotal = 0;

    object oGoods = GetFirstItemInInventory();
    while (GetIsObjectValid(oGoods))
    {
        // count how many Goods are in the crate
        if (GetTag(oGoods) == "warehouse_goods")
            iTotal++;

        if (iTotal == 5)
            break;

        oGoods = GetNextItemInInventory();
    }

    // if the quota is met
    if (iTotal == 5)
    {
        switch (iState)
        {
            case 11:
                iState = 21;
            break;

            case 51:
                iState = 61;
            break;

            case 91:
                iState = 101;
            break;

            case 131:
                iState = 141;
                SendMessageToPC(oPC, "You have become a respected member of the community"
                    + " and may continue loading goods to your heart's desire.");
            break;

            case 171:
                iState = 181;
                SendMessageToPC(oPC, "You have completed this quest"
                    + " but may continue loading goods to your heart's desire.");
            break;
        }

        if (bLabor)
            AddJournalQuestEntry("job_laborer2", iState, oPC);
        else
            AddJournalQuestEntry("job_laborer1", iState, oPC);

        // destroy goods
        iTotal = 0;

        oGoods = GetFirstItemInInventory();
        while (GetIsObjectValid(oGoods)
                && iTotal < 5)
        {
            // don't destroy more than 5 Goods per onClose
            if (GetTag(oGoods) == "warehouse_goods")
                DestroyObject(oGoods);

            iTotal++;
            oGoods = GetNextItemInInventory();
        }
    }
}
--
Above, considers the two journal threads as running in parallel; 'laborer1' always updates on 5 items, while 'laborer2' updates in parallel only when an Appraise DC is successful.

Modifié par kevL, 02 juillet 2014 - 04:37 .


#16
Dann-J

Dann-J
  • Members
  • 3 161 messages

I have a similar quest in a module I'm working on, except it involves carrying several heavy chests and dropping them onto a palette. The OnUnaquire script for the item checks to see if there is no valid owner (which means you dropped it on the ground), and if so destroys the dropped item and spawns a usable chest placeable that has no inventory. Clicking on the chest placeable picks it up (ie. destroys the placeable and spawns the item in your inventory).

 

I placed several ipoints with identical tags on the destination palette, which the OnUnaquire script checks for in a certain radius. Dropping a chest within range of one of the ipoints makes the spawned chest placeable non-usable and destroys that ipoint. It also positions the chest according to the location and bearing of the ipoint, so they look nice and neat on the palette and won't overlap each other. A conversation with someone in the same area as the palette checks how many of the ipoints remain, and when none do it makes a conversation node available that ends the quest.

 

I then had someone else give another quest to move the same chests to another palette in another area (you end up spending lots of quality time with those heavy chests). A script makes all the chest placeables usable again so they can be picked up, and spawns new destination ipoints elsewhere.



#17
4760

4760
  • Members
  • 1 204 messages

I need it to update several other journal entries.

 

AddJournalQuestEntry("job_laborer1", 21, oPC);

AddJournalQuestEntry("job_laborer1", 61, oPC);

AddJournalQuestEntry("job_laborer1", 101, oPC);

AddJournalQuestEntry("job_laborer1", 141, oPC);

AddJournalQuestEntry("job_laborer1", 181, oPC);

 

I have several quests in my campaign working the same way, and in your case I'd have something like

void UpdateQuest(string sJournal, int iQty)
{
	object oPC = GetFirstPC();
	if (sJournal == "") sJournal = "job_laborer1"; // refer to main quest by default
	int nEntry = 21 + (iQty - 1) * 40;
	AddJournalQuestEntry(sJournal, nEntry, oPC);
}

However this means your entries need to be sorted, so the "switch (iState)" solution is the way to go if you don't want to renumber.

But believe me, for your main quest/journal, you'd want to avoid all the "if" and "switch" lines, especially if you want it to be bilingual (here's how I do it for example:

10 text in English

11 text in French, male character

12 text in French, female character

20 same quest, second progress, English

21 same quest, second progress, French, male character

22 etc...



#18
Friar

Friar
  • Members
  • 293 messages

Hey KevL,

 

It's a strange pickle I've put myself in. Essentially, the player talks to a clerk who gives him the quest to talk to a foreman for work. If the player uses his appraise skill he can negotiate for 2 gp per job rather than 1 gp.

 

If he successfully negotiates 2 gp then the conversation gives the player the "job_laborer2" quest. If not then the conversation will give the "job_laborer1" quest and the player can only hope to earn 1 gp per job.

 

So the clerk gives the quest and it is posted at entry 1

The PC talks to the foreman.

Foreman explains the job and PC's journal updates to entry 11

The player puts the sacks in a crate and the journal updates to entry 21

The player talks again to the clerk, gets paid by the clerk, and the entry updates to 31

 

The player runs the quest again

goes to clerk journal updates this time to entry 41

goes to foreman journal updates this time to entry 51

places sacks in crate updates to entry 61

talks again to clerk,paid, and it updates to 71

 

player talks to clerk - 81

talk to foreman - 91

fills the crate - 101

reports to clerk for payment - 111

 

Pc to clerk -121

PC tp foreman - 131

to crate - 141

to clerk and is paid - 151

 

This last one should loop because by this time the 151 entry is completed then some new dialogue options appear and the player can pretty much move on or keep breaking his back doing physical labor.

 

Pc goes to clerk - 161

Foreman is overjoyed to see the character again, gives work - 171

loads crates the same as always - 181

gets paid with no raise in sight - 191

 

repeat and rinse to 161, 171 etc etc

 

The other kicker is that the crate needs to be able to update on both "job_laborer1" and "job_laborer2" iStates.

 

 

The only thing I could think of was to get conversations and journal entries to distinguish between the two pay rates. It seems like a messy way to do it, but I guess that's how Im doing it. The conversations are doing their part with conditionals, but I think the script on the crate wants to only update the journal back to ("job_laborer", 21, oPC)

 

 

@DannJ

That's a smart idea about the ipoints.

 

@4760

It's unfortunate I do not speak French and I'm going to revisit your idea because I'm not sure yet that it is what I am looking for. Still your answer is appreciated. :)



#19
4760

4760
  • Members
  • 1 204 messages

The way I see it, you've got two options:

1) put all journal entries in the same "job_laborer" journal, and it's a local variable (attached to the PC or to the clerk, doesn't matter) that will decide which half of the journal to use. Say that between 0 and 300 it's 1 gp, and 2 gp otherwise:

void UpdateQuest(int iEntry)
{
	object oPC = GetFirstPC();
        int bHighPay = GetLocalInt(oPC, "bHighPay");
        if (bHighPay) iEntry+= 300;
	AddJournalQuestEntry(sJournal, iEntry, oPC);
}
 

In this case, your journal entries 11, 21, 31 etc... will have to be 311, 321, 331 etc... for the 2 gp variante.

Note that in this case, you provide the exact entry number.

 

2) keep two separate journals, with the same structure. To update the quest, you'd have something like:

void UpdateQuest(int bHighPay)
{
	object oPC = GetFirstPC();
        // other possibility: bHighPay is a local variable, in which case not needed as a parameter
        // int bHighPay = GetLocalInt(oPC, "bHighPay");
        sJournal = "job_laborer1";
	if (bHighPay) sJournal = "job_laborer2"
	int iJournal = GetJournalEntry(sJournal, oPC);
	iJournal += 10;
	AddJournalQuestEntry(sJournal, iJournal, oPC);
}

Here, the journal entries have the same numbers.

Note that in this case, the entry is automatically updated (add 10 to the last entry), all you have to provide is the value to decide if it's job_laborer1 or job_laborer2 that will be used. But even this is not really necessary if you work with a variable (remove the // before int bHighPay, and of course delete "int bHighPay" in the function parameters).



#20
Friar

Friar
  • Members
  • 293 messages

No doubt I need to make this more simple.

 

But I'm afraid to combine the two journal strings because that means I'd need to go back and fix all the conversations that look for it. Complicated huh?

 

One bit of good news is that I think I could kill the journal entry that says the player has talked to the foreman.

 

It isn't necessary for triggering any of the events. The player can just load the crate and get an update telling them to talk to the clerk and get paid. Unless I could use it to tell the crate script which journal it should update. oh my stars this is making my head hurt.



#21
kevL

kevL
  • Members
  • 4 056 messages

ok, updated the script above.

 

It's pretty simple and I don't think you have to change much ... either in script or dialog

 

 

 

ps. Fine tuning depends on how the conversation is setup.



#22
Friar

Friar
  • Members
  • 293 messages

 

Try this out, but i warn you I don't quite understand what you're getting at w/ the two journal threads.
 

// Put this script OnClose
// - relies on "warehouse_goods" (items in crate) all having the same Tag.

void main()
{
    int iTotal = 0;

    object oGoods = GetFirstItemInInventory();
    while (GetIsObjectValid(oGoods))
    {
        // count how many Goods are in the crate
        if (GetTag(oGoods) == "warehouse_goods")
            iTotal++;

        if (iTotal == 5)
            break;
        oGoods = GetNextItemInInventory();
    }

    // if the quota is met
    if (iTotal == 5)
    {
        object oPC = GetLastClosedBy();
        if (!GetIsPC(oPC))
            return;

        int iState = GetJournalEntry("job_laborer1", oPC);
        switch (iState)
        {
            case 0:
                iState = 21;
            break;

            case 21:
                iState = 61;
            break;

            case 61:
                iState = 141;
            break;

            case 141:
                iState = 181;
                SendMessageToPC(oPC, "You have become a respected member of the community"
                    + " and may continue loading goods to your heart's desire.");
            break;

            default:
                SendMessageToPC(oPC, "You have completed this quest"
                    + " but may continue loading goods to your heart's desire.");
            break;
        }

        AddJournalQuestEntry("job_laborer1", iState, oPC);

        if (Random(20) < GetSkillRank(SKILL_APPRAISE, oPC))
        {
            AddJournalQuestEntry("job_laborer2", iState, oPC);
            GiveGoldToCreature(oPC, Random(2) + 1);
        }


        iTotal = 0;

        oGoods = GetFirstItemInInventory();
        while (GetIsObjectValid(oGoods)
                && iTotal <= 5)
        {
            // don't destroy more than 5 Goods per onClose
            if (GetTag(oGoods) == "warehouse_goods")
                DestroyObject(oGoods);

            iTotal++;
            oGoods = GetNextItemInInventory();
        }
    }
}
--
Above, considers the two journal threads as running in parallel; 'laborer1' always updates on 5 items, while 'laborer2' updates in parallel only when an Appraise DC is successful.

 

 

The good news is that the script would only need to go on the crate so the crate itself won't be paying out 1 gp or 2 gp to the player. So if the player puts the goods in the crate then only the journal needs to update appropriately. The rest is worked out in conversations.

 

Conversations will look for which journal entry is updated in the conditions under

Script: gc_journal_entry

sQuestTag: job_laborer1 / job_laborer2

sCheck (String): blah blah

 

All the crate must do is empty like it's been doing when it gets full and then updating the journal so the player can get paid each time. Im just not sure of how it will distinguish which journal string it's on and then which entry its already done and which entry it should update to next.



#23
kevL

kevL
  • Members
  • 4 056 messages

yep. I updated the script a minute ago (removed payment &tc)



#24
Friar

Friar
  • Members
  • 293 messages

Thanks kevL,

You've really been a big help at this.

 

I did plug the script into the crate to see if it works, but it isn't responding.

The one you came up with back in January does but as you can see it doesn't fully answer the many needs this needy little quest has.

 

Any idea why? I noticed some lines missing at the beginning, but wasn't sure if that was to get another part to work or ..



#25
kevL

kevL
  • Members
  • 4 056 messages

Does PC have either journal "job_laborer1" or "job_laborer2" ? if not, the close event does nada.

i can put debug in to show where its failing ... if you want


The 'missing lines' aren't missing; they've been moved ( and the safety checks put up at the top instead )

 

oh, and make sure you have the latest version of the script ......