Aller au contenu

Photo

The Merely Impossible Things


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

#1
La Rose Noire

La Rose Noire
  • Members
  • 25 messages
This post is to remember what is impossible to do in a nwn script and help new programers. Add your owns and if you see somethnig wrong, everyone can post a solution to help.
  • Delay à CreateObject without an include.


  • Store an effect as local variable to retrieve it later.


  • Store a location on an item as local location


  • AssignCommand on a trigger


  • Play Fight Animations with PlayAnimation

Modifié par La Rose Noire, 10 janvier 2011 - 11:02 .


#2
Baaleos

Baaleos
  • Members
  • 1 329 messages
Just providing a solution to this

CreateObject via Delay - The reason this fails when attempting to Delay it, is because nwnscript doesnt allow DelayCommand to work with functions that return values. To Fix this, and make CreateObject work, you need to wrap it in a 'void' function.



But yes, everything else is impossible, at least, not doable with out of the box functions.

eg - Location after all, is just area, x,y,z and orientation etc - these are store-able if converted to strings, which is what aps_include does for SetPersistentLoation functions.

#3
Shadooow

Shadooow
  • Members
  • 4 468 messages
You can store effect with workaround like you create a creature in area and apply it to it, then you store the creature tag and to retrieve you get creature from tag and then first effect. Not nice but can work for permanent duration effects. (Another way could be rebuild effect from integer/string, but you can not set most effect properties directly like caster...)

#4
Baaleos

Baaleos
  • Members
  • 1 329 messages
Theres an idea - yeah, if you use StoreCampaignObject or SetPersistentObject via nwnx, this would store the Creature, at the state it was when it was stored.



Would it be retrieved with the effects intact?



Also-

The Effect Creator is used when deciding who is responsible for things like 'Someone damaged you' etc.

In terms of Persistently storing a creature with an effect, then bringing them back, and taking the effect, and applying it again to another creature.

Would the original effect creator still get credit for the effect.



eg - I create an effect Petrification - Apply to Goblin

Store the Goblin

Reset Server

Bring back Goblin from database

Get the first Effect on the Goblin,

Apply to a new Goblin - Who would get credit for the Petrification?



I know nwnx_funcs for windows, and probably Linux, allows the setting of Effect Creator within the Effect, which suggests that the creator, is stored as an object ref inside the effect struct itself, if this is the case, after a server reset, the obj ref will likely not point to the correct player, and result in it defaulting back to 'Someone' opposed to 'Me'

#5
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Baaleos wrote...
eg - I create an effect Petrification - Apply to Goblin
Store the Goblin
Reset Server
Bring back Goblin from database
Get the first Effect on the Goblin,
Apply to a new Goblin - Who would get credit for the Petrification?


The object that applied the effect to the new goblin would becom the new Effect creator.

Edit: Bad information.

Modifié par Lightfoot8, 10 janvier 2011 - 06:55 .


#6
Baaleos

Baaleos
  • Members
  • 1 329 messages
I thought the effect creator was always the one who takes credit for things like damage etc.



eg - If the Module creates an effect, and then the player is assigned a command, to apply the effect to himself, then it would still say that 'Someone' damaged him?



That being said, I havent personally tested this, It was just my belief that this was how it operated.

I may have been wrong.

#7
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Baaleos wrote...

I thought the effect creator was always the one who takes credit for things like damage etc.


This is correct  the Object that is denoted as the creator is the one that gets the credit.

eg - If the Module creates an effect, and then the player is assigned a command, to apply the effect to himself, then it would still say that 'Someone' damaged him?

 I was looking for an old post from AxeMurderer on this but was unable to find it. 
  I am unsure what happens when a PC damages hinself. 
If the damage  effect is created by the module then assigned to the PC to apply it to a goblin. 
The PC would end up being the effect creator and get the credit for damaging the goblin.
 

EDIT; Bad Information 

Modifié par Lightfoot8, 10 janvier 2011 - 06:56 .


#8
Shadooow

Shadooow
  • Members
  • 4 468 messages
Well its not so simple.

If you define and effect in script which runs on module like this:

void main()
{
object oPC = GetEnteringObject();
effect e = EffectHaste();
AssignCommand(oPC,ApplyEffectToObject(DURATION_TYPE_PERMANENT,e,oPC));
}

It is still module who is creator. If it would be EffectDeath I believe that player would see message that "someone killed his name". Well it matter only when racial/alignment immunity concerned, but it may be important. Also this effect will have spellID -1, as it was defined outside spell script which is special for effects.

To change player to be creator the PC must assign a function where the effect will be defined or the effect must be defined in the assign line like:

AssignCommand(oPC,ApplyEffectToObject(DURATION_...,EffectDeath(),oPC));

Then the effect creator will be PC.

If we are retrieving effects from creature like I suggested with GetFirst/NextEffect, the effect retain old creator.

Modifié par ShaDoOoW, 10 janvier 2011 - 06:30 .


#9
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
OOPs
Shadow is right.  Sorry for the glitch in my memory.  
This does however add a problem to trying to store the effects over resets. 
Since all objects in the game are dynamically assigned. It is unlikely the effect creator will be correct on the restart of the module.

#10
Shadooow

Shadooow
  • Members
  • 4 468 messages
Yea thats the problem, but there may be solution in desing of what the OP need storing effect for. Maybe its solution to logging off from server for the while before some negative effect pass off? Well anyway, I believe that this issue can be workarounded.

#11
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Lists like this are problematic, since you can work around most things to the point that the limit is irrelevant. The remaining hard limits tend to be widely dispersed, unrelated, and often unconsequential.

For example, since I don't see this mentioned below, you CAN store location as a local - you just have to reformat it first, as a location string and a location area object. We have functions for this in our master include:

string GetPositionStringFromVector (vector vPos) {
    return FloatToString(vPos.x, 1, 2) + ", " +
           FloatToString(vPos.y, 1, 2) + ", " +
           FloatToString(vPos.z, 1, 2);
}

string GetPositionStringFromLocation (location lLoc) {
    vector vPos = GetPositionFromLocation(lLoc);

    return "[" + GetPositionStringFromVector(GetPositionFromLocation(lLoc)) +
        " | " + FloatToString(GetFacingFromLocation(lLoc), 1, 0) + "]";
}

string GetPositionString (object oObject) {
    return GetPositionStringFromLocation(GetLocation(oObject));
}

location GetLocationFromString (object oArea, string sLoc) {
    float fFacing;
    vector vVec;

    vVec = Vector(StringToFloat(GetStringSubString(sLoc, 0, ",")),
                  StringToFloat(GetStringSubString(sLoc, 1, ",")),
                  StringToFloat(GetStringSubString(sLoc, 2, ",")));
    fFacing = StringToFloat(GetStringSubString(sLoc, 3, ","));

    return Location(oArea, vVec, fFacing);
}


Area can be stored directly as a local object, obviously. Of course, you're storing this on an item, which might mean you want it to persist across resets. In that case, you'd have to find another way to store the area - like tag, looping through areas to find the object.

Funky

Modifié par FunkySwerve, 10 janvier 2011 - 11:17 .


#12
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Just one note on storing the Area as a local object on an item. Since the Object Id for the area is assigned dynamically. There is no garentee that the Area stored in Local Object will be the same area you stored on the object, Over a server reset. There is however a good chance the area will be the same one stored as long as no area have been added to or removed from the module. For LocalObjects stored other then areas there is just about 05 chance that they would be the same.

If you did want to store an area as a local on an object, It would be more secure to di it by storing the area's tag as a string.  You would also have to make sure all of your areas had a unique tag.


Edit; added the phrase "over server reset".  Somehow I missed placing that in.

Modifié par Lightfoot8, 11 janvier 2011 - 12:09 .


#13
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

Lightfoot8 wrote...

Just one note on storing the Area as a local object on an item. Since the Object Id for the area is assigned dynamically. There is no garentee that the Area stored in Local Object will be the same area you stored on the object. 

There is an absolute guarantee that they're the same, unless the server has reset - a separate case I dealt with above, and the reason for the alternate suggestion of storing area tag instead. Unless you include things like nwnx_areas, though I can't see instanced areas altering previously assigned object ids without a reset (I just can't say there's an 'absolute guarantee' there, not having used nwnx_areas).

Funky

Modifié par FunkySwerve, 11 janvier 2011 - 12:00 .


#14
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Yes,  I somehow missed the phrase 'over server resets' in my previous post.  I have edited it to correct the possible miscommunication. 
The real point here is that it is problematic to store LocalObjects onto items.  Yes they can be stored but the data is no good after a reset.  Since the stored Local Object can, after a server reset, Point to a completely different valid Object. The storing of local Objects onto items, should only be done with great care. If ever.

Modifié par Lightfoot8, 11 janvier 2011 - 12:20 .


#15
Greyfort

Greyfort
  • Members
  • 234 messages
I generaly if just using nwn DB have a campaign data base "DB_moddata" that can be saved on a creature in a area called mod_data totaly removed from player accsess you then just call that at mod load and poof vars restored.

// v1 nwndb sample
void main()
{
// you can use this to set and get data from nwndb
// not the most conventional but stable and works through resets
object oDataObj;//use function to id player char if applicable
// creature,placeable,etc...
string sCampaignName="DB_moddata";
string sVarName="var_name"+GetTag(oDataObj)+"";
object oCreature=GetObjectByTag("npc_tag");
GetCampaignString( sCampaignName, sVarName, oCreature);
}

note: as above mentioned certain objects cannot be used with DB, and with the nwn DB you most offten use Strings to store data then return them to what you need float, int etc. so you have to on mod load get the data then depending on if object placeable, player, etc most then be loaded on as local. Funk and Light are right local vars dont stay :( 
EDIT ADD:  If you would like a example of above let me know I will post it on the vault.

Modifié par Greyfort, 11 janvier 2011 - 05:29 .


#16
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages

Greyfort wrote...
 Funk and Light are right local vars dont stay :( 


I am not sure what you mean by this one.   Locals dont stay on what ?


As far as your DB method It sounds a lof like the one Knat put on the vault.   You may want to check it out.  If you use DMFI 1.09  NBDE is already a part of it, it just need to be activated in the module.

[NBDE] Natural Bioware Database Extension v1.0

#17
Greyfort

Greyfort
  • Members
  • 234 messages
Lightfoot wrote: *The real point here is that it is problematic to store LocalObjects onto items. Yes they can be stored but the data is no good after a reset. Since the stored Local Object can, after a server reset, Point to a completely different valid Object. The storing of local Objects onto items, should only be done with great care. If ever*



I was agreeing with you and funk on that issue, and so far the only way I know to restore any local vars(string,int,object,etc) is store them into DB and recall the DB at modload/ client ent to set the Local vars. Did I explain that better?

#18
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
Yes, Thank you.

#19
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
I thought the area IDs stayed the same so long as you did not add or alter areas in your module in the toolset and then "build" your module. Seems like one of the things we figured out through trial and error. So long as we did not alter the module we didn't have any issues with people returning to stored local areas on database items that the player carried even over resets. I could be wrong but that seemed to be the case for us.

#20
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
You are correct Ghost,



Basicly every object in the game is given an ID#. The module is always ID 0.

The areas are added to the list next from the Module Info file. Giving them ID's of 0-X

Where X is the number af areas you have in the module.

So as long as you do not change the module the areas should load to the same ID's every time.

This is at least what my tests have shown without looking at the machine code.

#21
Baaleos

Baaleos
  • Members
  • 1 329 messages
With regards to Funky's concern above about whether nwnx_areas might cause complications, I dont think it is currently coded to re-use memory space that is deleted.



eg - Area made, Area Deleted, Area Made



The Areas are made at the end of the list I think, if they were made to fill in the gap's, then it might cause problems, but in a server instance, the local object id for areas should remain constant, or OBJECT_INVALID for cases where an area is deleted.



The only possible exception, I think, might occur, is if the last area in the list is deleted, then the Adding of a new area, might take its place, because from what I can remember, it does increase and decrease the area count, which might cause a newly added area, to get the area id of the previously deleted area.



Note - the order in which objects are created, also offsets object id's.

More areas = more id's that are used, and more creatures = more object id's

#22
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages
Wuhay too many posts on storing locations. To top it all off, I noticed on a reread of the thread that Baaleos actually DID mention location storage via string in his first reply.  :P

Anyway, in an effort to get the thread back on track, here's an old compilation of data-getting functions made by Sunjammer some years back, showing which don't work on certain objects (mostly GetResRef). It's out of date, now, since I think some now work that didn't back then, but many should remain accurate.

----------------|------|------|--------|-----
 Object         | Type | Name | ResRef | Tag 
----------------|------|------|--------|-----
 Module         | 0    | Y    | N      | Y
 Area           | 0    | Y    | N      | Y
 Player (PC)    | 1    | Y    | N      | N
 Creature       | 1    | Y    | Y      | Y
 Item           | 2    | Y    | Y      | Y
 Trigger        | 4    | Y    | Y      | Y
 Door           | 8    | Y    | N      | Y
 Area Of Effect | 16   | N    | N      | Y*
 Waypoint       | 32   | Y    | N      | Y
 Placeable      | 64   | Y    | Y      | Y
 Merchant       | 128  | Y    | N      | Y 
 Encounter      | 256  | Y    | N      | Y 
----------------|------|------|--------|-----
* an AOE is tagged with the LABEL column from vfx_persistent.2da

If someone wants to spend the time to update it, that'd be handy.

Funky

#23
GhostOfGod

GhostOfGod
  • Members
  • 863 messages
Hmmm. I'm sorry to keep going with the location thing. It's just that I'm confused i guess. The topic of this post has to do with things that are impossible in NWN script. And one of the things that was listed as impossible was:

Store a location on an item as local location

But of course we have the function "SetLocalLocation" which I use on items and it works fine.

So I guess I'm just asking if this is something that does not belong on this list of impossible things?


#24
FunkySwerve

FunkySwerve
  • Members
  • 1 308 messages

GhostOfGod wrote...

Hmmm. I'm sorry to keep going with the location thing. It's just that I'm confused i guess. The topic of this post has to do with things that are impossible in NWN script. And one of the things that was listed as impossible was:
Store a location on an item as local location
But of course we have the function "SetLocalLocation" which I use on items and it works fine.
So I guess I'm just asking if this is something that does not belong on this list of impossible things?

My assumption is that she meant persisting across resets, or in the toolset.

Funky

#25
Lightfoot8

Lightfoot8
  • Members
  • 2 535 messages
The 'AssignCommand on a trigger' From the original post can also be done.   I Just finished testing it.  It worked fine.