• Welcome to SC4 Devotion Forum Archives.

Script in Reader

Started by ilive, March 28, 2010, 01:41:42 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

ilive

Scripts under Reader can be done using LUA language (v5.1)
LUA 5.1 reference manual is available at http://www.lua.org/manual/5.1/manual.html

If you need some requests, don't hesitate  ;)

User Interface
Don't forget to define the script directory in the Option screen.
To use script, open a DAT file and use the following ribbon

the combo list is filled with all lua scripts found in the defined script directory
the first icon is to create a new script
the second icon is not use at the moment
the third icon is to edit the script selected in the combo
the two last icons is to save and save as the script

when you edit the script, a new tab is created.

the first icon is to save the script
the second icon is to compile the script (but the script is not executed)
the third icon is to run the script
the fourth icon is to stop the script

the top pane displays the code, the bottom pane displays output messages

Coding
Entry point for Reader is the reader.main function.
Each script has to begin with the following line "function reader.main (this)" and is ended with "end" word.
There is no function to save the DAT. You have to save the DAT manually after checking that all your modifications are ok.

example 1

   function reader.main (this)   
      pos = reader:entries_GetHeadPosition()     
      while pos~=0 do
      entry,pos = reader:entries_GetNext(pos)
      flag = reader:entry_GetFlag(entry) 
      if (flag == 7) then
         exemplar = reader:ex_Decode(entry)
         dw1,dw2,dw3 = reader:ex_GetParentCohort(exemplar)
         dw1= 0x0000001
         dw2= 0x0000002
         dw3= 0x0000003
         reader:ex_SetParentCohort(exemplar,dw1,dw2,dw3)

         proppos = reader:exprop_GetHeadPosition(exemplar) 
         while proppos~=0 do
            exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
            desc,descname = reader:exprop_GetDesc(exprop)       
            if (desc == 0x27812837) then
               reader:exprop_SetDesc(exprop,0x12345678)
               io.write("descname :",descname)
            end
         end       
         reader:ex_Encode(entry,exemplar)
      end
      end
   end

   This example parse all entries of a Dat file.
   If an entry is an exemplar, it changes the Parent Cohort.
   If a property desc of this exemplar is 0x27812837, it changes this property to 0x12345678.
   Once done, it encodes the data to save modifications.
   
example 2
   function reader.main (this)   
      pos = reader:entries_GetHeadPosition()     
      while pos~=0 do
      entry,pos = reader:entries_GetNext(pos)
      flag = reader:entry_GetFlag(entry)     
      if (flag == 2) then      
         s3d = reader:s3d_Decode(entry)   
         count = reader:s3d_Count(s3d, 4)
         io.write("count :",count )
         block = reader:s3d_GetBlock(s3d, 4, 0)
         pos = reader:s3dtext_GetHeadPosition(block)
         while pos ~=0 do
            s3dtext, pos = reader:s3dtext_GetNext(block,pos)
            id, wrapModeS, wrapModeT,magFilter, minFilter,name = reader:s3dtext_GetInfo(s3dtext)
            if (id==0x00030403) then
               io.write("id:",name)
               id = 0x00000001
               name="test_lua"
               reader:s3dtext_SetInfo(s3dtext, id, wrapModeS, wrapModeT,magFilter, minFilter,name)
            end
         end   
         reader:s3d_SetBlock(s3d, 4, 0, block)
         reader:s3d_Encode(entry,s3d)
      end
      end
      reader:refresh()
   end
   
   This example parse all entries of a Dat file.
   If an entry is a S3D, it reads material block (4) then parses all textures.
   If id of one of them is 0x00030403, it changes to 0x00000001 and changes its name.   
   Once done, it encodes the data to save modifications.




-----------------------------------------------------------------------------
List of functions
-----------------------------------------------------------------------------

Entries/Entry group
   refresh()
         Refresh the main list in the reader
   count = entries_Count()   
         Get the number of elements in the entries list
   pos = entries_GetHeadPosition()
         Get the position of the head element of the entries list
   entry, pos = entries_GetNext(pos)
         Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   T,G,I = entry_GetTGI(entry)
         Get the Type/Group/Instance of an entry
   entry_SetTGI(entry,T,G,I)
         Set the Type/Group/Instance of an entry
   Flag = entry_GetFlag(entry)
         Get the flag of an entry (see Annex 1 for list of value)

Exemplar group
   exemplar = ex_Decode(entry)      
         Decode the entry to fill the exemplar struct
   ex_Encode(entry,exemplar)
         Encode exemplar values and fill the entry
   ex_Release(exemplar)
         Release an exemplar (if modification has to be canceled)
   TC,GC,IC = ex_GetParentCohort(exemplar)
         Get the Type/Group/Instance of the Parent Cohort property
   ex_SetParentCohort(exemplar,TC,GC,IC)
         Set the Type/Group/Instance of the Parent Cohort property
   pos = exprop_GetHeadPosition(exemplar)
         Get the position of the head element of the properties list
   exprop, pos = exprop_GetNext(exemplar,pos)
         Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   exprop = exprop_Add(exemplar)
         Add a new property
   exprop_Del(exemplar,pos)
         Delete a property
   desc,name = exprop_GetDesc(exprop)
         Get description of the property (desc is the hexadecimal value, name is the string value)
   exprop_SetDesc(exprop,desc)
         Set description of the property
   type = exprop_GetType(exprop)
         Get type of the property
         Type can be
            PROP_UINT8     0x100
            PROP_UINT32    0x300
            PROP_SINT32    0x700
            PROP_SINT64    0x800
            PROP_FLOAT32   0x900
            PROP_BOOL      0xB00
            PROP_STR       0xC00
   exprop_SetType(exprop,type)
         Set type of the property          
   rep = exprop_GetRep(exprop)
         Get Rep of a property
   exprop_SetRep(exprop,rep)
         Set Rep of a property
   valuestr = exprop_GetValueStr(exprop)
         Get the complete value of a property in a string
   result = exprop_HasValueStr(exprop, value)
         Return 1 if the property has the value, 0 otherelse
         Value depends on the type of the property. If type is 0xC00, value has to be a string.
   exprop_SetValue(exprop, value, [idx])
         Set the value of a property.
         Idx has to be filled it you want to change a value in an array
   
S3D Group
   s3d = s3d_Decode(entry)   
      Decode the entry to fill the s3d struct   
   s3d_Encode(entry,s3d)   
      Encode s3d values and fill the entry
   s3d_Release(s3d)
      Release a s3d (if modification has to be canceled)
   count = s3d_Count(s3d, block_id)
      Get the number of element depending on block ID
      Block ID can be :
       1 : vertices
       2 : indexes
       3 : primitives
       4 : material
       5 : animation
   block = s3d_GetBlock(s3d, block_id, index)
      Get the data block adressed by index
   s3d_SetBlock(s3d, block_id, index, block)
      Set the data block
   s3d_ReleaseBlock(block_id, block)
      Release the data block (if modification has to be canceled)
   
block 4      
   flags, alphafunc, depthfunc,srcBlendFactor,dstBlendFactor,alphaThreshold = s3dmat_GetInfo(block)
      Get information about material block
      flags values :
            0x0001 - enable alpha test
                0x0002 - enable depth test
                0x0008 - enable backface culling
                0x0010 - enable framebuffer blending
                0x0020 - enable texturing
                0x0040 - enable depth writes (unused - currently set by code)
                0x0080 - enable color writes (unused - currently forced on)
        alpha func, depthfunc :
              0 - never
            1 - less than
                2 - equal
                3 - less than or equal
                4 - greater
                5 - not equal
                6 - greater than or equal
                7 - always
      srcBlendFactor,dstBlendFactor
            0 - zero
                1 - one
                2 - source color (destination factor only)
                3 - one minus source color (destination factor only)
                4 - source alpha
                5 - one minus source alpha
                8 - destination color (source factor only)
                9 - one minus destination color (source factor only)      
   s3dmat_SetInfo(block,flags, alphafunc, depthfunc,srcBlendFactor, dstBlendFactor,alphaThreshold)
      Set information about material block
      
   pos = s3dtext_GetHeadPosition(block)
      Get the position of the head element of the texture list
   s3dtext, pos = s3dtext_GetNext(block,pos)
      Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   s3dtext = s3dtext_Add(block)
      Add a new texture
   s3dtext_Del(block,pos)
      Delete a texture
   id, wrapModeS, wrapModeT,magFilter, minFilter,name = s3dtext_GetInfo(s3dtext)
      Get information about texture
         wrapModeS,wrapModeT :  Texture addressing mode for S (U)/ T (V)  texture axis
            2 - clamp
            3 - repeat
         magFilter : Texture magnification filter hint 
            0 - nearest
            1 - bilinear
         minFilter : Texture minification filter hint 
            0 - nearest, no mipmapping
            1 - bilinear, no mipmapping
            2 - nearest mipmap nearest
            3 - linear mipmap nearest (bilinear with mipmapping)
            4 - nearest mipmap linear
            5 - linear mipmap linear (trilinear)
         name :  Null-terminated name of texture               
   s3dtext_SetInfo(s3dtext, id, wrapModeS, wrapModeT,magFilter, minFilter,name)
      Set information about texture   
      
block 1      
   pos = s3dvert_GetHeadPosition(block)
      Get the position of the head element of the vertices list
   s3dvert, pos = s3dvert_GetNext(block,pos)      
      Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   s3dvert = s3dvert_Add(block)
      Add a new vertex
   s3dvert_Del(block,pos)
      Delete a vertex
   vertex_format = s3dvert_GetFormat(block)
      Get the format of the vertex
   s3dvert_SetFormat(block, vertex_format)
      Set the format of the vertex
   x,y,z = s3dvert_GetInfoPos(s3dvert)
      Get the world position
   s3dvert_SetInfoPos(s3dvert, x,y,z)
      Set the world position
   b,g,r,a = s3dvert_GetInfoColor(s3dvert)
      Get the diffuse color
   s3dvert_SetInfoColor(s3dvert, b,g,r,a)
      Set the diffuse color
   u0,v0,u1,v1 = s3dvert_GetInfoCoord(s3dvert)
      Get the first/second texture coordinate
   s3dvert_SetInfoCoord(s3dvert, u0,v0,u1,v1)
      Set the first/second texture coordinate
      
block 3      
   pos = s3dprim_GetHeadPosition(block)
      Get the position of the head element of the primitives list
   s3dprim, pos = s3dprim_GetNext(block,pos)
      Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   s3dprim = s3dprim_Add(block)
      Add a new primitive
   s3dprim_Del(block,pos)
      Delete a primitive
   type, first, count = s3dprim_GetInfo(s3dprim)
      Get information about primitive
      type
         0- triangles
         1- triangle strip
         2 - triangle fan
         6 - quads
         7 - quad strips
      first : first vertex used by primitive
      count : Number of vertices used by primitive        
   s3dprim_SetInfo(s3dprim, type, first, count)
      Set information about primitive

block 2      
   pos = s3didx_GetHeadPosition(block)
      Get the position of the head element of the indexes list
   s3didx, pos = s3didx_GetNext(block,pos)
      Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   s3didx = s3didx_Add(block)
      Add a new index
   s3didx_Del(block,pos)
      Delete an index
   t1,t2,t3 = s3didx_GetInfo(block,s3didx)
      Get information about index
   s3didx_SetInfo(block, s3didx, t1, t2, t3)
      Set information about index
   
block 5   
   frameCount,frameRate,animMode,displacement = s3danim_GetInfo(block)
      Get information about anim
      animMode
          0 - ping pong
          1 - one -shot
          2 - loop 
   s3danim_SetInfo(block, frameCount,frameRate,animMode,displacement)   
      Set information about anim
   pos = s3dmesh_GetHeadPosition(block)
      Get the position of the head element of the meshes list
   s3dmesh, pos = s3dmesh_GetNext(block,pos)
      Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   s3dmesh = s3dmesh_Add(block)
      Add a new mesh
   s3dmesh_Del(block,pos)
      Delete a mesh
      
   pos = s3dfrm_GetHeadPosition(s3dmesh)
      Get the position of the head element of the frames list
   s3dfrm, pos = s3dfrm_GetNext(s3dmesh,pos)
      Get the list element identified by pos, then sets pos to the POSITION value of the next entry in the list
   s3dfrm = s3dfrm_Add(block)
      Add a new frame
    s3dfrm_Del(block,pos)
      Delete a frame
    vertBlock,indexBlock,primBlock,materialBlock = s3dfrm_GetInfo(s3dfrm)
      Get information about frame
    s3dfrm_SetInfo(s3dfrm, vertBlock,indexBlock,primBlock,materialBlock)
      Set information about frame
      
      


Annex 1.
List of flags
S3D            2
FLG_ANIM      3
FLG_BMP         4
Cohort         5
FLG_EACS      6
Exemplar      7
FLG_MCO         8
FLG_F1B         9
FLG_HIT         10
FLG_JFIF      11
FLG_LEV         12
FLG_NA         13
FLG_PNG         14
FLG_RUL         15
FLG_SC4PATH      17
FLG_FSH         18
FLG_TRK         19
FLG_UI         20
FLG_UNKNOWN      21
FLG_MAD         22
FLG_WAVE      23
FLG_XA         24
FLG_DBPF      25
FLG_LUA        26
FLG_HLS        27
FLG_TLO        28
FLG_LTEXT      29
FLG_DIR        30
FLG_U1         31
FLG_KEYCFG     32
FLG_PRE_BMP    33
FLG_PRE_XA     34
FLG_EFF_DIR    35
FLG_U2         36
FLG_LD         37
FLG_SAVE_TAXES    38
FLG_SAVE_MYSIM    39
FLG_SAVE_ADV      40
FLG_SAVE_ORD      41
FLG_SAVE_PNG      42
FLG_SAVE_WILD     43
FLG_SAVE_REQ      44
FLG_DELOC         45
FLG_INI           46
FLG_SAVE_BUY_POWER    47 
FLG_SAVE_SELL_POWER   48
FLG_SAVE_BUY_WATER    49
FLG_SAVE_SELL_WATER   50
FLG_SAVE_EXT_GARB     51
FLG_SAVE_IMP_GARB     52
FLG_SAVE_ADV_FIN      53
FLG_SAVE_ADV_UT       54
FLG_SAVE_ADV_ALL      55
FLG_SAVE_ADV_SIM      56
FLG_AB           57
FLG_AE           58
FLG_XML          59      
      
      
      
            

fafalone

This is an excellent feature, if I had discovered the new version a few days ago I would saved hours with this, but I've got a bunch of other large projects in the works and this will save tons of time.

Merci pour ce logiciel extraordinaire :)

Lowkee33

#2
Hi all,

I am trying to make one tree controller to rule them all. &cry2

There are 256 reps of the FloraPreferences, so I have started with 256 exemplars.  Each exemplar has it's own unique "1" in an otherwise 255 reps of 0 (Exemplar 1: 1,0,...0, Exemplar 2: 0,1,...,0 , Exemplar 256: 0,0,...,1).  Following my flora range and a "2", each exemplar is sequenced in the 6th and 7th digits (0x33AA2000, 0x33AA20100,...,0x3AA2FF0).  Flora is best in clusters, so my plan was to simply clone each exemplar 15 times and increase the Instance by 1 (To fill up the entire 0x2### range).  This would make every exemplar in the cluster have a "1" in the same place in FloraPreferences.  Very nice, it took about 45 minutes to set the Preferences up for the final cloning.

Testing it out today, this will not do.  The last flora in a cluster appear with far too much strength.  To combat this I made the values in the Preferences decrease by .5 for each next flora in the cluster (1, .95, .9,...,.25), and I am pleased.  However, I estimate setting up these Preferences to take about 12 hours...

...Probably faster to learn LUA scripting.  I have an idea for a pretty simple script, but I have no idea how to implement it.  It would gather the value of each Rep and then subract a divisor and place it back in.  I would then clone the file, change the divisor and repeat.

Is anyone familiar with scripting for Reader?  All of these commands are pretty abstract to me.  Example 1 looks in Ilive's post looks pretty close to my idea, particularly the 1st half.

Quotedw1,dw2,dw3 = reader:ex_GetParentCohort(exemplar)
         dw1= 0x0000001
         dw2= 0x0000002
         dw3= 0x0000003
         reader:ex_SetParentCohort(exemplar,dw1,dw2,dw3)

If I could change the ParentCohort to FloraPreferences and use dw1-dw256 and then use math on them, I would be totally happy.

Thanks

Edit: so close and yet so far.  Thought I had it figured out, but Reader can only hold 195 variables...  Guess I only need 16, so time for some looping... 

Lowkee33

#3
Guess I only need 2 variables.
function reader.main (this)
   A0= 0
   A1= 1
   pos = reader:entries_GetHeadPosition()
   repeat
   repeat
       entry,pos = reader:entries_GetNext(pos)
   exemplar =  reader:ex_Decode(entry)
proppos = reader:exprop_GetHeadPosition(exemplar)
exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
reader:exprop_SetValue(exprop, A1, A0)
reader:ex_Encode(entry,exemplar)
  A1= A1-(1/16)
  until (A1 == 0)
  A1= 1
  A0= A0+1
  until (A0 == 256) end


This will make changing "Exemplar Name" and "Flora: Cluster Type" much faster too.  Took near 7 hours, but at least I learned something and could drink soda at the same time. :) 

There are a few things I had to wrap my head around, so this I will share.  All functions must have "reader:" before them (for "rep = exprop_GetRep(exprop)" to work, one needs to write "rep = reader:exprop_GetRep(exprop)").  Also, in this case, "rep" (not "Rep") is a variable, and can be anything that doesn't start with a number and isn't a Lua command.  This variable can also be used in other "Set" functions.

In the function "exprop_SetValue(exprop, value, [idx])": "value" is what you want to set the property to be, and "[idx]" is the Rep of the property.

The script I wrote starts with defining two variables "A0" and "A1".  You can see later on that I have used these variables as the "value" and "rep" of the SetValue function.  It then goes to the head of the .dat file, and then goes into a loop.  It selects the next entry (which would be us clicking on the top entry) and decodes it.  I couldn't figure out "go to property" so in this case, I have the script basically scrolling down until it gets to the 4th property (notice we are in "proppos" not "entry" functions) which is the FloraPreferences.  It sets the value of the property, at this point setting the "0" rep to "1".  The exemplar is recoded.  1/16 is then subtracted from A1 and set to be A1.  Since A1 does not equal zero, it goes back to the repeat, selecting the next exemplar, scrolling down 4 properties, but now setting the FloraPref to have .9375 as the 0 rep.  This continues until A1=0, at which point it resets A1 to 1, and adds 1 to A0 (so now we are on the "1" rep), and repeats the -1/16 process. This continues until A0=256, and we have reached the end of the 4096 exemplars. :)




Ilive's examples have functions like get(this), if this=that, then prevail.  These are basically checks to make sure the correct property is selected.  After the 4th "exprop, proppos = reader:exprop_GetNext(exemplar,proppos)" I could have written:

desc,name = exprop_GetDesc(exprop)
if (desc == 0x083DC847) then
-Set the values-


This code would have checked to make sure the 4th property was "0x083DC847" (which is the value for FloraPref) before setting the values of the reps.  For me, I knew all of my exemplars where just clones of each other, and didn't need any checking.  While learning this script, I used this code followed by the "io.write("descname :",descname)" (which prints the property name) function to make sure I was in the right place.

Thinking about potentials now, I imagine with some knowledge the verticies of a model could be measured to find the exact volume of a model.  I also wonder about a cohort maker.

Frex_Ceafus


Lowkee33

#5
Thanks there Frex_Ceafus

Quote from: toja on September 21, 2011, 10:41:08 AMBut maybe we should continue our conversation in the Script in Reader-topic?

Sounds fine.

I've been editing U,V values with Excell, but it's kind of lame.  ::)  I moved on to trying to get a script to do it, but I'm having troubles.

I made a simple model, and here are the Vertex Values: 



For this post, I've copy/pasted a zoom 4 S3D into its own file (so the script is pretty light/specific)

function reader.main(this)

pos= reader:entries_GetHeadPosition()
entry,pos= reader:entries_GetNext(pos)
s3d = reader:s3d_Decode(entry)
block = reader:s3d_GetBlock(s3d, 1, 0)
s3dpos= reader:s3dvert_GetHeadPosition(block)

while s3dpos ~=0 do
  s3dvert, s3dpos= reader:s3dvert_GetNext(block,s3dpos)
  u0,v0,u1,v1 = reader:s3dvert_GetInfoCoord(s3dvert)
  print (u0)
end

// Testing to see if it's just me...

  u0,v0,u1,v1 = reader:s3dvert_GetInfoCoord(s3dvert)
  print (u0)
  s3dvert, s3dpos= reader:s3dvert_GetNext(block,s3dpos)
  u0,v0,u1,v1 = reader:s3dvert_GetInfoCoord(s3dvert)
  print (u0)

reader:s3d_Encode(entry,s3d)
end


Basically, we're just going through the Vertices and printing the values.  I've also thrown the lines at the bottom in to check if I'm using the while loop wrong.  The output is this:

0.46666669845581
0.53333336114883
0.26666665077209
0.13333332538605
0.73333334922791
0.86666667461395

// testing

0.86666667461395
nil
.


The first issue is that these are the V values.  In fact, u0 is the only variable that comes up with anything.  Second, I can't get the last vertex to print.  I first re-get it and print to see if it's the while loop.  Then manually get the next position with a print-back of "nil".

Any Ideas?

toja

#6
I've examined the file ReaderLua.cpp from the source code and I think I know what's happening here: The C-function s3dvert_GetInfoCoord() collects four values but than it returns only three of them to the LUA interpreter. And it seems as if it's not the only function with this behaviour. As far as I can see the following functions do return the wrong number of values:

   b,g,r,a = s3dvert_GetInfoColor(s3dvert)
   u0,v0,u1,v1 = s3dvert_GetInfoCoord(s3dvert)
   frameCount,frameRate,animMode,displacement = s3danim_GetInfo(block)
   vertBlock,indexBlock,primBlock,materialBlock = s3dfrm_GetInfo(s3dfrm)

There's nothing we can do here, we can only wait for a bugfixed version... Have you tried to set your new UV-coordinates without calling s3dvert_GetInfoCoord before? I don't see a reason why it shouldn't work.

I'm not really sure why it's not possible to access the last vertex in a group, but I think it's another bug in the function s3dvert_GetNext (), to be more precise: line #985 in ReaderLUA.cpp

The following code seems to be a workaround, at least I was able to get the x,y,z-values for the last vertex   :)


function reader.main(this)
...
local counter = 0     ---- we're counting the while loops with this variable
while s3dpos ~= 0 do
  counter = counter + 1
  s3dvert, s3dpos = reader:s3dvert_GetNext(block,s3dpos)
  local x, y, z = reader:s3dvert_GetInfoPos(s3dvert)
  print (x, y, z)

  -- now we're using the variable counter to get the last vertex
  if (s3dpos == 0) then
    local last_s3dvert = reader:s3dvert_GetNext(block, counter + 1)
    x, y, z = reader:s3dvert_GetInfoPos(last_s3dvert)
    print (x, y, z)
  end
end
end




Lowkee33

hmm, I've gone as far as copy/pasting this into my script, but Reader becomes unresponsive after I run it.  Could it be I need something special for "local"?

toja

Ah, there was an error in the code, my mistake, I'm sorry. I've declared the variables s3dvert and s3dpos as local inside the while-loop which makes it run forever. I've updated the code above, it should be correct now.

Lowkee33

Works like a charm.  :thumbsup:

Gets the 7th vert value too, but still missing the real u0.



Lior

#10
Well, I'm a begginer on modding, so sorry for my ignorance. What's this script for? What's its function?

toja

@Lowkee33: I'm glad to hear that it works now, although I can't help with the u0 value. It would be really easy to fix the bug, but I don't have the possibility to recompile the source code.

@Lior: It's only a code snippet, that allows you to read the coordinates of an S3D model and print them to the console window. It becomes useful when you want to change the coordinates of all S3D models in a file with only one click via LUA

Lowkee33

@Lior: Passed what Toga said, it's hard for me to explain without writing a manuscript.

  Suffice to say, that first image I posted (Link), is the part of the model that defines the way the S3D and FSH files interact.  The S3D is a series of points creating triangles (the LOD), and the FSH is an image that is laid over the LOD.  The X,Y,Z, values are the position of the point (meters) in a 3D grid, and the U,V values are the position of the point on the FSH image (%).

  Normally there are 20 FSH for a model, but I've been trying to make mine only have one.  This means that the U,V values need to be scaled down for the lesser zooms (they may have been a %80 of a 16x16 image, but only %20 for a 64x64 pixel FSH).

  So, like I said, this can be done in Excell, but much less chance of error with a script.  First step is to get and print the right values.  After that there is some math to do, and then the final set value.  Looks like I'm not going to get passed that first step though.

fafalone

Anyone know how to get the previous property position?

I'm trying to automate deleting properties, the relevant section is:

         while proppos~=0 do
            exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
            desc,descname = reader:exprop_GetDesc(exprop)
            if (desc == 0x27812820) then
               io.write("found at pos :",proppos)
               reader:exprop_Del(exemplar,proppos)
            end
         end

This deletes the property that comes AFTER the given property. And I can't simply subtract 1, since the proppos is 121890252 and the item before it is 121890188 (and the one before that was 121891484, yes higher). This only seems to apply to delete... if I change anything it's applied to the correct item.

Has anyone been working with the script feature and can offer any insight?

fafalone

I think everyone who uses the script feature should post their scripts here, so everyone can learn better.

Right now I'm using a script that helps automate things I have to do on the huge number of lots in my projects.

What it does is identifies the exemplars in a file, checks to make sure it isn't the LotConfigurations exemplar (which has a parent cohort of 0,0,0), then sets the parent cohort, sets the lot name (so its not PZ_grass2358973057), and adds an ItemOrder property. I'm still trying to figure out how to get it to delete properties correctly.

   function reader.main (this)   
      pos = reader:entries_GetHeadPosition()     
      while pos~=0 do
      entry,pos = reader:entries_GetNext(pos)
      flag = reader:entry_GetFlag(entry)
      if (flag == 7) then
         crex= 0
         exemplar = reader:ex_Decode(entry)
         dw1,dw2,dw3 = reader:ex_GetParentCohort(exemplar)
         if (dw1==0) then
            crex= 1
         end
         if (crex ~= 1) then
         dw1= 0x05342861
         dw2= 0xB6A644F7
         dw3= 0xA584310F
         reader:ex_SetParentCohort(exemplar,dw1,dw2,dw3)

         proppos = reader:exprop_GetHeadPosition(exemplar)
         while proppos~=0 do
            exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
            desc,descname = reader:exprop_GetDesc(exprop)
            if (desc == 0x00000020) then
               io.write("found namedesc")
               reader:exprop_SetValue(exprop,"MHTRM_Lot")
            end
         end

         exprop = reader:exprop_Add(exemplar)
         reader:exprop_SetType(exprop,0x300)
         reader:exprop_SetDesc(exprop,0x8A2602B9)
         reader:exprop_SetValue(exprop,0x00000000)
         reader:exprop_SetRep(exprop,1)
         end     
         reader:ex_Encode(entry,exemplar)
      end
      end
   end

memo

#15
I have once tried to get the script feature working for me (and I could well have used it FREQUENTLY), but I could not get it to run properly, at all. Either the reader constantly crashed or the script did not show any effect, although I am pretty sure the script was correct. This was rather demotivating and I have stuck to 0.93 since. &mmm


Edit: As for your problem with deleting properties, maybe you could do a workaround and simply save the previous position into a variable in order to reference it for the deletion.

toja

#16
QuoteAs for your problem with deleting properties, maybe you could do a workaround and simply save the previous position into a variable in order to reference it for the deletion.
or in lua:


         while proppos~=0 do
            previous_proppos = proppos
            exprop, proppos = reader:exprop_GetNext(exemplar,proppos)
            desc,descname = reader:exprop_GetDesc(exprop)
            if (desc == 0x27812820) then
               io.write("found at pos :", previous_proppos)
               reader:exprop_Del(exemplar, previous_proppos)
            end
         end


Quote from: memo on January 28, 2013, 02:47:45 PM
Either the reader constantly crashed or the script did not show any effect, although I am pretty sure the script was correct.

Did your script generate any output the console? The reader crashes, when you print more than just a few lines to the console.

rabidcow

The deal with the console output is that there's an off-by-one error that will cause a buffer overflow if you write more than 255 characters within about a tenth of a second.

Also, exprop_SetRep and exprop_SetValue are mostly broken; you can only set string values and elements of existing arrays.

Nique

#18
How do i enable multiple flags? i mean, in LUA 5.1 there is no bitwise operator so im kinda screwed here..
I need all of them

0x0001 - enable alpha test
0x0002 - enable depth test
0x0008 - enable backface culling
0x0010 - enable framebuffer blending
0x0020 - enable texture




Edit: I fixed it by installing luaforwindows and use the bit.dll package in my script (btw nice snippet for everyone who wants to make their props transparent 'fast':

------------------------------------------------------------------------------------
-- S3D TRANSPARENCY.LUA - By Nique de Graaff                                      --
--   You MUST install luaforwindows in the default installation folder for        --
--   this to work! Then run this in the ILives Reader on your sc4model            --
------------------------------------------------------------------------------------
-- This script will:                                                              --
--   Enable framebuffer blending                                                  --
--   Set Alpha Func to "Always"                                                   --
--   Set Src Blend to "Source alpha"                                              --
--   Set Dest Blend to "one minus source alpha"                                   --
------------------------------------------------------------------------------------

dir = "C:/Program Files (x86)/Lua/5.1/clibs/"
package.cpath = dir.."?.dll"
require("bit")

function reader.main (this) 
       
        pos = reader:entries_GetHeadPosition() 

        while pos ~= 0 do
               
                entry,pos = reader:entries_GetNext(pos)
                flag      = reader:entry_GetFlag(entry)

                if (flag == 2) then
                       
                        s3d    = reader:s3d_Decode(entry)
                        count  = reader:s3d_Count(s3d, 4)-1

                        for i=0,count do

                                block  = reader:s3d_GetBlock(s3d, 4, i)
                                s3dpos = reader:s3dtext_GetHeadPosition(block)         
                         
                                while s3dpos ~= 0 do                   
                                        s3dtext, s3dpos = reader:s3dtext_GetNext(block,s3dpos)
                         
                                        flags, alphafunc, depthfunc,srcBlendFactor,dstBlendFactor,alphaThreshold = reader:s3dmat_GetInfo(block)
                                        flags          = bit.bor(flags, 0x0010)       
                                        alphafunc      = 7
                                        srcBlendFactor = 4
                                        dstBlendFactor = 5
                         
                                        reader:s3dmat_SetInfo(block, flags, alphafunc, depthfunc,srcBlendFactor, dstBlendFactor,alphaThreshold)
                                end                   
                         
                                reader:s3d_SetBlock(s3d, 4, i, block)                               
                       
                        end

                        reader:s3d_Encode(entry,s3d)
                end
        end

        io.write("\nDone!")
        reader:refresh()
end
Proudly developer of

Durfsurn

I am trying to write a script that changes S3D values in the Mats tab (wrapModeS, wrapModeT, magFilter & minFilter) and can't seem to quite understand LUA in iLives. I have used a little tad bit of LUA before but it seems not enough. This is what I have so far;

function reader.main (this)   
id, wrapModeS, wrapModeT,magFilter, minFilter,name = reader:s3dtext_GetInfo(s3dtext)
if (wrapModeS== 3) then
  io.write("2", wrapModeS)
  id = 2
  name="script"
  reader:s3dtext_SetInfo(s3dtext, id, wrapModeS, wrapModeT,magFilter, minFilter,name)
end
  end 
reader:s3d_SetBlock(s3d, 4, 0, block)
reader:s3d_Encode(entry,s3d)
end
end


I tried to reuse some code form the original post as well.
Maybe someone has already done a similar script?

Thanks
-Billy