Author Topic: The Merely Impossible Things  (Read 733 times)

Legacy_La Rose Noire

  • Newbie
  • *
  • Posts: 49
  • Karma: +0/-0
The Merely Impossible Things
« on: January 10, 2011, 10:59:40 am »


               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 .
                     
                  


            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
The Merely Impossible Things
« Reply #1 on: January 10, 2011, 11:48:42 am »


               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.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
The Merely Impossible Things
« Reply #2 on: January 10, 2011, 01:32:27 pm »


               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...)
               
               

               
            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
The Merely Impossible Things
« Reply #3 on: January 10, 2011, 01:50:41 pm »


               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'
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The Merely Impossible Things
« Reply #4 on: January 10, 2011, 03:57:49 pm »


               

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 .
                     
                  


            

Baaleos

  • Administrator
  • Hero Member
  • *****
  • Posts: 1916
  • Karma: +0/-0
The Merely Impossible Things
« Reply #5 on: January 10, 2011, 04:05:19 pm »


               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.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The Merely Impossible Things
« Reply #6 on: January 10, 2011, 05:23:24 pm »


               

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 .
                     
                  


            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
The Merely Impossible Things
« Reply #7 on: January 10, 2011, 06:29:42 pm »


               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 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The Merely Impossible Things
« Reply #8 on: January 10, 2011, 06:52:41 pm »


               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.
               
               

               
            

Legacy_Shadooow

  • Hero Member
  • *****
  • Posts: 7698
  • Karma: +0/-0
The Merely Impossible Things
« Reply #9 on: January 10, 2011, 07:20:08 pm »


               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.
               
               

               
            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
The Merely Impossible Things
« Reply #10 on: January 10, 2011, 11:11:45 pm »


               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 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The Merely Impossible Things
« Reply #11 on: January 10, 2011, 11:21:54 pm »


               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 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
The Merely Impossible Things
« Reply #12 on: January 10, 2011, 11:57:53 pm »


               

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 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
The Merely Impossible Things
« Reply #13 on: January 11, 2011, 12:19:08 am »


               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 .
                     
                  


            

Legacy_Greyfort

  • Sr. Member
  • ****
  • Posts: 442
  • Karma: +0/-0
The Merely Impossible Things
« Reply #14 on: January 11, 2011, 04:53:47 am »


               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 '<img'> 
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 .