STRUCT on Module

Hello again. One more challenge (for me, probably not for you). I’m working with a structured variable and need to save the contents for future reference on the module level. I constantly use the SetLocal* for saving module-level variables, anyone know how to save a struct to the Module? Is there a SaveLocalStruct() (couldn’t find it) or something that does the same thing? SaveLocalObject()? I know I can break it apart and save the individual values on the Module and then recreate the struct when necessary, but that kind of defeats the purpose of the struct to begin with. Any ideas here?

AFAIK there’s no way to save a struct on the module or any other object.

Structs are very useful, but when storage on object is a key purpose, a pseudo-struct is preferable. This is nothing more than a set of local variables (with a common variable name prefix that groups them together). Pseudo-structs also lend themselves to pseudo-arrays, whereas a true array of structs is not supported.

This is assuming vanilla NWN for SP - other things may be possible with MP server extensions and/or data bases.

Proleric,

Once again, thanks. I assumed that was the answer, but thanks for confirming it.

Alternatively you write your own routines like I did here for pseudo arrays of vectors. The downside is you can’t create generic routines because each struct type is for all intents and purposes more or less unique, which is why the only thing resembling a struct that you can save locally are things of the object data type (which like a lot of other built in types can be regarded as structs-plus).

TR

You could do something like the following:

struct foo
{
    int    a;
    string b;
    object c;
};

struct foo GetLocalFoo()
{
    object oModule = GetModule();
    struct foo bar;
    bar.a = GetLocalInt   (oModule, "Foo");
    bar.b = GetLocalString(oModule, "Foo");
    bar.c = GetLocalObject(oModule, "Foo");
    return bar;
}

void SetLocalFoo(struct foo bar)
{
    object oModule = GetModule();
    SetLocalInt   (oModule, "Foo", bar.a);
    SetLocalString(oModule, "Foo", bar.b);
    SetLocalObject(oModule, "Foo", bar.c);
}

Tarot…

Thanks, I’ll definitely look onto that project.

SM,

I created three routines that look exactly like that, one each for save, get and delete, so I might go that route. I need to routinely update one of the members of the struct and I’ll already have the name for it, so it’ll probably be faster just to reference the variable name directly rather than recreating the struct, updating the variable, resaving the struct. May use the routines for creation and deletion, then reference the individual variables for the routine updates.

Thanks for the input. Seeing others come up with similar ideas helps me believe I’m not insane from staring at code.

There is yet another approach. You can serialize the struct into a string:

struct mystruct
{
    int    a;
    float  b;
    string c;
};

string mystruct2string(struct mystruct stStruct)
{
    // 0 in FloatToString eliminates leading whitespace
    return IntToString(stStruct.a) + "÷" +
        FloatToString(stStruct.b, 0) + "÷" +
        stStruct.c;
}

You recover the struct by splitting the string by the delimiter, then passing each component to StringTo* functions. The ÷ character is from extended ASCII range so it has low chance of appearing in “normal” in-game strings.

This has the advantage that you can SetLocalString just once with all data inside, but requires de-serialization every time you want to make changes to any part of the struct. It doesn’t work directly with vectors, locations and objects, but you can always store a Tag…

Promo.

I use the above paradigm to construct dynamic lists here. They work well up to few thousands of elements.

Thanks. I don’t think this will be efficient with my particular script because I’m constantly interacting with only one member of the struct. If I was changing more, it would work perfectly. However, I’m definitely keeping this in my example repository. Thanks for help!