nwnxee / unified

Binaries available under the Releases tab on Github
https://nwnxee.github.io/unified
GNU General Public License v3.0
131 stars 92 forks source link

Feature request: barter before/after events #156

Closed weavejester closed 5 years ago

weavejester commented 6 years ago

Some servers, particularly PWs, have a script that runs ExportSingleCharacter periodically. I've just discovered that this cancels the player barter window ("Barter cancelled").

I'm not sure whether this is possible, but adding a before and after barter event to the events plugin might be useful, so that periodic scripts that save the player characters can be turned off for the duration.

Obviously this isn't high priority, but I thought I'd put it in here both as a future idea, and as a note for Google to find in case some PW scripter is tearing their hair out trying to find out why bartering isn't working :)

mtijanic commented 6 years ago

in case some PW scripter is tearing their hair out trying to find out why bartering isn't working

Ah, so that's why! Thanks. And good request, I'll get to it eventually if no one beats me to it.

mtijanic commented 6 years ago

Actually.. do we need the events, or would it be enough to just add something like GetBarteringWith(oPC) which returns oOtherPC if barter is active, or OBJECT_INVALID if not bartering currently.

We could also expose the bartering state (i.e. who locked the list, who accepted it), iterating through bartered objects, etc. Although, at this point it might be best to just have a new plugin.

weavejester commented 6 years ago

A GetBarteringWith function is a great idea, and would certainly fit this use-case even better.

That said, if we had a bartering event, we could derive a GetBarteringWith function by having the 'before' event set a local object on the PC, and having the 'after' event clear it. Something like:

// before
#include "nwnx_events"
#include "nwnx_object"

void main()
{
    object oPC = NWNX_Object_StringToObject(NWNX_Events_GetEventData("NWNX_BARTERING_WITH_ID"));
    SetLocalObject(OBJECT_SELF, "NWNX_BARTERING_WITH", oPC);  
}
// after
void main()
{
    DeleteLocalObject(OBJECT_SELF, "NWNX_BARTERING_WITH");
}
// include file
object GetBarteringWith(object oPC)
{
    return GetLocalObject(oPC, "NWNX_BARTERING_WITH");
}

That is more work for end users though, even if it is potentially more flexible.

mtijanic commented 6 years ago

Oh, actually, we discussed this afterwards, how about something like:

const int NWNX_BARTER_ACTION_INITIATE     = 0;
const int NWNX_BARTER_ACTION_ADD_ITEM     = 1;
const int NWNX_BARTER_ACTION_REMOVE_ITEM  = 2;
const int NWNX_BARTER_ACTION_EXAMINE_ITEM = 3;
const int NWNX_BARTER_ACTION_LOCK_LIST    = 4;
const int NWNX_BARTER_ACTION_ACCEPT       = 5;
const int NWNX_BARTER_ACTION_CANCEL       = 6;

struct NWNX_Barter_Info
{
    object oInitiator;
    object oTarget;
    int nLastAction;
    object oLastActor; // either oInitiator or oTarget
    object oLastActionItem;
};
struct NWNX_Barter_Info NWNX_Barter_GetInfo();
void NWNX_Barter_SetScript(string sScript);
object NWNX_Barter_GetFirstBarteredItem(object oBarterer);
object NWNX_Barter_GetNextBarteredItem(object oBarterer);

void NWNX_Barter_DoAction(object oActor, object oTarget, int nAction, object oItem = OBJECT_INVALID, int bTriggerBarterScript=FALSE);

Making it possible to script bartering with NPCs or Placeables.

weavejester commented 6 years ago

That would be pretty incredible! 👍