Author Topic: Always changing  (Read 499 times)

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Always changing
« on: December 03, 2012, 08:51:04 pm »


                <staring out to sea...>

I have in mind something for this month's CCC: Spoils, but it's something I haven't seen any discussion about, which probably means it's impossible.

There was one thread a couple years back, but all the suggestions were work-arounds and slieght of hand. 

Can we change appearance of a placeable the way we can with characters (polymorph), items, heads/helmets and body-parts?

What function is being called to make the actual appearance change? Can it be adapted to work on placeables?

My idea? A pile of treasure that grows/shrinks based on the value of the items/gold it contains. Say 10 different models of coins and gems and what-not of increasing size. 

Anyone ever dig into this?

<...waiting for his ship to come in>
               
               

               
            

Legacy_henesua

  • Hero Member
  • *****
  • Posts: 6519
  • Karma: +0/-0
Always changing
« Reply #1 on: December 03, 2012, 09:12:56 pm »


               You can't change the appearance of a placeable. BUT it is just as effective to create another placeable at the exact same location and orientation, then destroy the original. I've done this with Project Q's campfire placeables and it is very convincing. They have a campfire, campfire with tripod, and campfire tripod with pot. The creation of the new and destruction of the old appears to happen almost instantaneously. In my case since this is a campfire that can be lit, you get just the slightest hiccup when the animation resumes on the new placeable, but you have to look for it since the two placeables exist simultaneously for an instant.
               
               

               
            

Legacy_Buddywarrior

  • Hero Member
  • *****
  • Posts: 512
  • Karma: +0/-0
Always changing
« Reply #2 on: December 04, 2012, 03:05:51 pm »


               This is a great idea for a magician doing tricks...

Rose on top of a table
speakstring "Abracadabra!"
VFX_IMP_STUN effect
the rose is now a rabbit.
crowd goes wild.
The Great Hazzini takes a bow.
               
               

               
            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Always changing
« Reply #3 on: December 04, 2012, 06:07:48 pm »


               <ruefully pulling up...>

Would have been nice... :-/

Well, I've modified the idea a bit and now I'm hoping for some participation from bit-wise old scripters =)

I'll make a base container placeable that will create/destroy dependent placeables based on the value of the items it holds.
The dependent placeables will be sized in binary fashion (i.e. the #2 is twice the volume of #1, #3 is twice the volume of #2, etc. They will all have the same origin, but be offset in different directions, with overlap. In fact, the first 3 will mostly just fill up the interior of the chest (with a little spillage).

The functionality should be something like:
  • Item added:Calculate total value. Scale (log?) value to 8-bits (with 9th model for overflow). Create bits that are 1. Destroy bits that are 0.
  • Item removed: Calculate total value remaining. Scale... etc.

So PC walks up to this huge pile of a dragon's hoard and starts grabbing (tons!) stuff. The pile shifts and shrinks. PC can't move. Puts most back. Pile grows. PC comes back later, but his best friend beat him to it :-)

What do you think?

<...rue and tossing it in the greens bin>
               
               

               


                     Modifié par Rolo Kipp, 04 décembre 2012 - 06:09 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Always changing
« Reply #4 on: December 06, 2012, 02:02:28 am »


               

Rolo Kipp wrote...

<ruefully pulling up...>

Would have been nice... :-/

Well, I've modified the idea a bit and now I'm hoping for some participation from bit-wise old scripters =)

Whoa,  Who are you calling old?





I'll make a base container placeable that will create/destroy dependent placeables based on the value of the items it holds.

Sounds good,  I myself would make it an invisiable base container placeable.   The other placable would hold no inventory but be usable,   Having the OnUsed event of created placeables  open the inventory screen of the invisiable one.  





The dependent placeables will be sized in binary fashion (i.e. the #2 is twice the volume of #1, #3 is twice the volume of #2, etc. They will all have the same origin, but be offset in different directions, with overlap. In fact, the first 3 will mostly just fill up the interior of the chest (with a little spillage).


Hmm,  I am not sure i like the double Idea,   I guess that before I could decide on that though I would need to know the size of each area you where going to try and fit the items into...   Hmm on reading this a second time, are you talking about sizing the placables or just adding more?    



The functionality should be something like:
  â€¢ Item added:Calculate total value. Scale (log?) value to 8-bits (with 9th model for overflow). Create bits that are 1. Destroy bits that are 0.

I do not really like the Idea of calculating off of total value. One uber sword could end up making a pile bigger then 200 potions. I think the calculation should be done off of InvSlotWidth•InvSlotHeight. That way the pile will be more representive of the Size of the loot.

As far as the log Question: Yes log base 2 will return the position of the largest bit set. nwscript only has a natural log so you will have to convert it from log base e to log base 2. so in nwscript logBase2(x) = log(x)/log(2)

  â€¢ Item removed: Calculate total value remaining. Scale... etc.

So PC walks up to this huge pile of a dragon's hoard and starts grabbing (tons!) stuff. The pile shifts and shrinks. PC can't move. Puts most back. Pile grows. PC comes back later, but his best friend beat him to it :-)

What do you think?

<...rue and tossing it in the greens bin>


I like the Idea.   I still dont like the double Idea though, Unless you are making each ring twice the area size of the one before.  Or rather 3 times the size of the inner ring.  

I think I would model it more after the way electrons fill an atom.   where the number of electrons in each shell is  2*n*n and the and the fill is in regular pattern.
 
               
               

               


                     Modifié par Lightfoot8, 06 décembre 2012 - 02:05 .
                     
                  


            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Always changing
« Reply #5 on: December 07, 2012, 06:17:05 pm »


               <pulling out his old paints...>

I'll put together some stuff this weekend to try to make it clearer.

Basically, the dependent placeables are a visual indication of the value in the hoard. So a value that renders down to 37, say, would be placeable 6 (32), placeable 3 (4) and placeable 1. All three would be displayed in a overlaping but non-replacing fashion. I.e, there'd be a big pile (6), and to the side a small pile (3) and some stuff in the bottom of the chest (1).

If the hoard was maxed out, there'd be the *huge* pile (9 = overflow) and all 8 smaller piles arranged to fill a radius of about 5m (the entire hoard would be 1 tile across).

Edit: or possibly 2 tiles across. But that would require builders make sure the hoard is in a big open area...

I like the idea of the dependent placeables opening the inventory, but why use a separate invisible placeable when the base object (0) would always be rendered?

<...and trying to get visual>
               
               

               


                     Modifié par Rolo Kipp, 07 décembre 2012 - 06:18 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Always changing
« Reply #6 on: December 08, 2012, 05:31:50 pm »


                The first thing that need to be done before working on any functions is to nail down the scale value.  

Rolo Kipp wrote...

 The dependent placeables will be sized in binary fashion (i.e. the #2 is twice the volume of #1, #3 is twice the volume of #2, etc. They will all have the same origin, but be offset in different directions, with overlap. In fact, the first 3 will mostly just fill up the interior of the chest (with a little spillage).



When you are saying #1, #2 and Number #3.  

 Are they bit numbers? 
#1 (0010)
#2 (0100) 
#3 (1000)   // Yes bits are 0 based.  

Or are they numbers? 
#1 (0001)
#2 (0010) 
#3 (0011) 


Bit Numbers
If they are Bit numbers.   The Scale would simply be your Total Chest Value(TCV) devided by a Scale Value(SV). 

Scale = TCV/SV;

That would give you no Bits set until you reached you SV. 
0         <TCV  >  SV     =  (0000)  // bits
SV      < TCV > 2SV   =  (0001)
2SV    < TCV > 4SV   =  (001?)  // ? means the value may or may not be set.   
4SV    < TCV > 8SV   =  (01??)
8SV    < TCV > 16SV   =  (1???)

If you wanted to shift the scale up one, so that the first bit was set with the first item placed in the chest,  you would just add the SV to the TCV before the division. 

Scale = (TCV+SV)/ SV

Giving you:

0         <TCV  >  SV      =  (0001)  // bits
SV      < TCV >  2SV    =  (001?)
2SV    < TCV >  4SV    =  (01??)   
4SV    < TCV >  8SV    =  (1???)


With a SV of  10,000 this would look like. 

0            <TCV  >  10,000   =  (0001)  // bits
10,000  < TCV >  20,000   =  (001?)
20,000  < TCV >  40,000   =  (01??)   
40,000  < TCV >  80,000   =  (1???)
...
64,000 <TCV> 128,000    = (1???_????)  // Bit 8 Set.  

Numbers
If they are numbers.   It would be a log base 2.  

Scale = log(TCV) / log(2)

 (TCV <  2)    =   0    (0000)
 (TCV<  4)    =   1     (0001) 
 (TCV<  8)    =   2     (0010) 
 (TCV<  16)  =   3     (0011)
(TCV<  32)   =   4     (0100)
(TCV<  64)   =   5     (0101)
(TCV<  128) =   6     (0110)
...
(TCV<  512) =   8     (1000)
...
(65,536<  TVC >   131,072) = 16   (0001_0000)
...
Scale = 31  is TCV 2.14 Billion.   The max number an NWN int can be.  ( 0001_1111)

It looks to me that if you used:

Scale = log( TCV * 2 ) / log(2)
 You would never go over 8 bits.   
               
               

               
            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Always changing
« Reply #7 on: December 08, 2012, 06:42:04 pm »


               <uncomfortably waffling...>

Bits (which was my original idea) are too linear. The threshold values for a placeable to spawn are simply too high at the low end and to low at the high end.

Numbers, on the other hand start out too slow and finish t0o large. Also, I want that overflow placeable triggered for amounts over the top end.

Still, the second progression is closer to what I envision. I was hoping to do this elegantly, but I think in the end a simple (but long) case statement will be a lot easier to read and implement :-/

The kind of progression I was looking for is something like:

Bits set           #       Value
00000000        0      TCV = 0
00000001        1     100< TCV    (10^2)
00000010        2      625< TCV   (25^2)
00000100        3      2,500< TCV   (50^2)
00001000        4      5,625<TCV     (75^2)
00010000        5     10,000<TCV    (100^2)
00100000        6      62,500<TCV   (250^2)
01000000        7      250,000<TCV  (500^2)
10000000        8      562,500<TCV   (750^2)
with TCV over 1 million triggering the overflow (#9) placeable.

And the remainders would be examined to spawn lesser placeables. I.e. A TCV of 300,000 would generate #7 (250,00gp) and #1-5, but *not* #6 (remainder was less than 62,500).

<...on the picket fence>
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Always changing
« Reply #8 on: December 10, 2012, 04:05:03 am »


               The cloest I have gotten so far is.  

Scale = (-1500.0 +sqrt(pow(1500.0, 2.0) - 8*(1402-TCV))) / 4

It produces:

Bit 0 =  100
Bit 1 = 1606
Bit 2 = 4630
Bit 3 = 10726
Bit 4 = 23110
Bit 5 = 48646
Bit 6 = 102790
Bit 7 = 223366
Bit 8 = 513670
Bit 9 = 1290886
               
               

               
            

Legacy_DM_Vecna

  • Hero Member
  • *****
  • Posts: 501
  • Karma: +0/-0
Always changing
« Reply #9 on: December 10, 2012, 07:11:55 am »


               Not to interupt but if memory serves there is a function in NWNX to change the appearance of a peaceable.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Always changing
« Reply #10 on: December 11, 2012, 06:57:21 am »


               ok, Since the formula part is just about done.  ( I do not think it is what you wanted because I made it 10 bits instead of 9.)

Here are some quickly thrown together functions. ( meaning I have done no testing)

const string ResRefPrefix = "???" ;

 int GetPlacableFlags( object oChest = OBJECT_SELF)
 {
    int nGPValue;
    object oItem = GetFirstItemInInventory( oChest );
    while (GetIsObjectValid(oItem))
    {
      nGPValue += GetGoldPieceValue(oItem);
      oItem = GetNextItemInInventory (oChest);
    }
    return  FloatToInt((-1500.0 +sqrt(pow(1500.0, 2.0) - 8*(1402-nGPValue))) / 4);
          // FloatToInt(log(nGPValue*2.0)/log(2.0));
 }

int GetCurrentdrawnPLCSet( object oChest = OBJECT_SELF)
{
    return GetLocalInt( oChest,"PLC_Drawn_set");
}

void StoreCurrentdrawnPLCSet( int nDrawnSet, object oChest = OBJECT_SELF )
{
    SetLocalInt( oChest,"PLC_Drawn_set",nDrawnSet);
}

void DestroyPLCsInSet(int nSet, object oChest =OBJECT_SELF)
{
   string sTagPreFix = ObjectToString(oChest);
   while(nSet)
   {
      int nFlag = nSet & -nSet;
      nSet ^=  nFlag;
      DestroyObject( GetObjectByTag(sTagPreFix + IntToString(nFlag)));
   }
}


void DrawPLCsInSet(int nSet, object oChest =OBJECT_SELF )
{

  string sTagPreFix = ObjectToString(oChest);
  string sResRef, sTag;
  while(nSet)
  {
    int nFlag = nSet & -nSet;
    nSet ^=  nFlag;
    sTag = sTagPreFix + IntToString(nFlag);
    nFlag = FloatToInt( log(nFlag*1.0)/log(2.0));
    sResRef = ResRefPrefix +IntToString(nFlag);
    location lLoc = GetLocation(oChest);

    CreateObject( OBJECT_TYPE_PLACEABLE, sResRef, lLoc, FALSE, sTag );
  }
}

void UpdateTresurePlacables(object oTresureContainer = OBJECT_SELF)
{
   int nOldSet = GetCurrentdrawnPLCSet(oTresureContainer);
   int nNewSet = GetPlacableFlags(oTresureContainer);
   int nChange = nOldSet ^ nNewSet;
 
  if ( nChange )
   {
      StoreCurrentdrawnPLCSet( nNewSet, oTresureContainer);
      DestroyPLCsInSet(nChange & nOldSet ,oTresureContainer );
      DrawPLCsInSet   (nChange & nNewSet ,oTresureContainer );
   }
}
 
void main()
{
   UpdateTresurePlacables();
}
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
Always changing
« Reply #11 on: December 11, 2012, 11:03:31 pm »


               Two things I did not do in the functions above.  

1)  Adjust the location where the placable is drawn.   I just was not sure where you wanted them drawn.    

2)   Mask out overflow bits.  ( Oversite.  And the formula still need a little adjusting to get it down to 9 bits.)
               
               

               
            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Always changing
« Reply #12 on: December 31, 2012, 10:00:54 pm »


               <staring at his assistant...>

I am speechless! <hardly>
I am agog! <well, *that's true>
I am absolutely amazed! <you are really overdoing it>
Er, yes.

LF, your script (with the right resref prefix) worked. It worked without errors. It worked without errors the *first* time. <whoa, old man. breathe. sit down. pour some brandy>

'Image
I mean... that's *never* happened before. <out with the bad, in with the good. drink>
Absolutely incredible.. *choke* *gasp* What?! Bother! <snail, boss. it's good for the heart ;->
Ack! <you really should help aluvian with that dragon>
Nonesense. She's a professional apprentice. It's what I pay her for. <assistant>
Assistant, apprentice. Yada yada. <the dragon will keep argentiel's hoard...>
Ack! Don't just flap there, bird! *Do* something! The poor lass is...

<...getting mangled by a mist dragon>
               
               

               
            

Legacy_Rolo Kipp

  • Hero Member
  • *****
  • Posts: 4349
  • Karma: +0/-0
Always changing
« Reply #13 on: December 31, 2012, 10:09:39 pm »


               <looking...>

I spoke too soon. <always do>
adding or subtracting gold does nothing. Only items...

And the formula isn't right... It takes a couple diamonds of preposterous value (2,000,000 each) and still doesn't flinch.
(I.e. with 4 million+ inside, I still haven't seen tier 7, 8 or 9...)
Edit: Triggered 8 with about 10 million in it. (guessing... it was a *lot* of Gems of Preposterous Price).
Edit 2: wrap around on the gems... 32K each, not 2 mil :-P

It doesn't show level 1 (a couple coins) until there's 3,000 (3 sapphires) inside.
Level 1 (or *a* level) should show if *anything* is inside.

Edit 3: Ok, the top end of the formula works, but it still takes an awful lot of value before the first few coins show. And gold doesn't count... so, when you can... :-P

<...for the money>
               
               

               


                     Modifié par Rolo Kipp, 01 janvier 2013 - 01:40 .
                     
                  


            

Legacy_FunkySwerve

  • Hero Member
  • *****
  • Posts: 2325
  • Karma: +0/-0
Always changing
« Reply #14 on: January 01, 2013, 12:37:41 am »


               I only read the first few posts (always an invitation to trouble), but I saw one incorrect thing which I thought I would clarify. You CAN change the appearance of placeables on the fly, with NWNX, the nwnx_funcs plugin's SetPlaceableAppearance. The problem with this approach, however, is in the comment:


/* Set oPlace's appearance. Will not update for PCs until they re-enter the area. */
int SetPlaceableAppearance (object oPlace, int nApp);

IIRC acaos and I tried varied ways around this, like setting things to cutscene invisible and back, to no avail. With critters, you can apply a very short polymorph effect to force the client to re-render (the basis of our !render command for the occasional single-client invisible critter caused by desync), but not with places.

As a result, the function is less useful than it could be, though it's still great for DMs designing areas wanting to see what various vfx look like applied near/on various placeable appearances - if you're using SIMTools you can dm_setvarstring NWNX!FUNCS!SETPLACEABLEAPPEARANCE *, where * is the appy number, on the fly - good fun.

Funky