Daraan on 5/12/2017 at 23:09
With the coming DScript1.0 there will be 3 major CreatorScripts, which main goal is to help you in DromEd instead of doing in game stuff. One if it is the AutoTxtRepl or AutoTexRepl or AutoTexRep or AutoTex .... can't decide. Suggestions what name you like more?
Texture Replacement Objects are great as you can add variety to the same shape but at the same time it could be kinda a hassle.
CoSaS beds with over 100 varieties. Many Replacement Picture Frames and Doors but what Textures to use? The Tree pack with X Tress Y Leaves and Z Barks. The Vegetation Pack 5 Bushes x 20 Textures. (
http://spirited-tech.com/thief/2017/12/05/book-collection-by-daraan/) The Book Collection with 29 covers (Off Topic non commercial advertising:tsktsk:) and and and...
But jahh checking which textures are available then edit object, add shape TexRepl write obj\txt16\ for the 100th time... that becomes annoying and maybe we just fall back to standard types.
THIS IS NOW OVER!
The Auto Texture Replacement Script automatically chooses textures based on the model.
<video controls="controls" height="480" width="640">
<source src="http://dl.dropboxusercontent.com/s/uxb9oy6zcwaoxoq/DAutoTxtRepl.mp4?dl=0" type="video/mp4"></source>
</video>
(http://collabedit.com/qt3ey) But for this a database is required. And that database needs your help! You also can and should add your own custom stuff. So CLICK ME (or first read about it ;)
So how does it work and look like.The script works with two table sets {Category=Models} and {Category=Textures} with categories as key-lock system. When it found the model in a category it will add a random texture from the same category from the texture table.
Code:
Models: Pictures=["NVPictureFrame","AnotherPicture]
Textures: Pictures=["Paint1","Paint2","picnic]
So for example if you create a model with the Shape->Model Name: NVPictureFrame it will add one of the textures ""Paint1","Paint2","picnic" to the TxtRepl r0 property of that object.
SyntaxSlot DefinitionBy default the Field 0 is used. By inserting a number (1-3) behind the model name this can be changed.
Code:
Models: Barks=["1aTree]
Leaves=["1aTree",1]
This will add a Barks texture to Field 0 and a Leaves texture to Field 1 and as you see the same model can be used in more than one category.
If your model uses more slots a sub texture table can be defined for example:
Code:
Models: Book=["DBook]
Textures: Book=
{
KeepIndex="01"
"0":["Book1-0,Book2-0]
"1":["Book1-1,Book2-1]
"2":["DPage2Text]
"3":["DBindBlack","DBindBlue]
}
This will add to Field 0 one of the textures from "0" to Field 1 one from "1" ....
Additionally with the KeepIndex variable it tells the script that the Field 0 and 1 should use textures with the same index so when Book2-0 gets randomed Book2-1 is chosen automatically.
The numbers should be enclosed by "" and : used instead of = !
Replacement SyntaxTextures&Models can be added in four different ways, as seen above as single texture
Code:
Textures: Key=["TextureName]
or also added automatically if they are in a numeric order ( so you don't have to write tex1, tex2,....)
Code:
Textures: Painting=["RipOff#",11,"RipOff#",13.16]
The # will be replaced by the row defined by the number added after the texture name. (The # can also be in the middle like: Book#-1 but not more than one # may be added)
For integer numbers it will add 1->n and for float/decimal numbers the integer part->decimal part so for above RipOff1,RipOff2,...RipOff11 will be created and RipOff13,...,RipOff16. Obviously the decimal part must be higher.
By default obj\txt16\ is the pre-added path. Other paths can be chosen but their full path needs to be written. NOTE that TWO \ are required!
Code:
Textures: Windows=["fam\\church\\glas1]
NEW:
A $ will be replaced by the entrys in an array in the slot directly behind the model or texture name:
Code:
"Model$",["A","B] -> "ModelA" , "ModelB"
All optional Variants can be combined but must be in the order Array,Float,integer
Code:
Models: "#$Worstcase",["a","b] , 1.2 , 3 -> a1Worstcase,3, a2Worstcase,3 ,b1Worstcase,3 ,b2Worstcase, 3
ParametersThe script is designed to work automatically without parameters but there are also some options beside the standard DBaseTrap Parameters.
Code:
DAutoTxtReplType=Category will add a random texture from the chooses Category into the TexRepl Field defined by DAutoTxtReplField (Default=0)
(Not yet implemented) DAutoTxtReplLock (similar to DAutoTxtReplCount=1) if a Field is already filled with a value it will not be rerandomed again and skipped. This allows for example the manual adjustments of objects.
DAutoTxtReplMode (Default=1)
// 0 will only work when TurnedOn (standard Trap behavior) Default: TurnOn and test via script_test ObjID
// 1 (Default) Not automatically in game.exe
// 2 Everytime when loaded. PRO: Works on in game.exe created objects CONTRA: Also executes after save game loads. Consider DAutoTxtReplCount=1 or Lock=1
NOTE: Mode=2 will for example change pictures or your bedsheets;) in the game.exe after every reload, could be kinda interesting.
What can you do?This database has two purposes.
a)Collecting Models and Textures(*) which fit into generic categories for example Picture Frames, Rocks, DoorFrames...While models can be added without limitations. Textures which are not present for the user will be blank and DromEd will throw a warning. (Squirrel Question:Is there a way to test if a texture is present? FindFileInPath looked promising but fails - I think it doesn't check subfolders :/ . Can you somehow grab the resname_base add \obj\txt16 to the contents and then save that as path variable to be used again?)
As this is a script for creators they(you) will realize when a texture is missing but I think we shouldn't hide good textures maybe move them to another commented array with information where to find them.
Even just creating fitting texture categories would be helpful with the use of (
http://spirited-tech.com/thief/2015/11/15/reskinnable-objects-by-yandros/) Yandros' generic reskinnable objects. or similar. You got a table model and want some Wood (frame) Textures....
b1)Adding your own Models and fitting TexturesCode:
Models: MyCategory=["MyModel]
Textures: MyCategory=["MyTexture]
This will help others who also use your model and this script to automatically texture it. Take my DBook as an example.
Also here you can assume if the model is present the textures will be too as they come from the same source.
b2)Creating Replacement Versions of existing sets.Kinda the same problematic: You have a few non replacement models, do you want to add them
all to your gamesys or manually edit the shape numerous times just to change the texture?
We could create Larry'sTarrotPictures->[1..30], CoSaS Books+Lamps+->[1...], Firemage' Dishes, Otto's Art Collection, Random Street Sign, Metal Decals and again and and and...
In the end just one hierarchy slot but the whole set variety without extra adjustments.
So where can I begin?
(
http://collabedit.com/qt3ey)
Link to the DatabaseI just took simple online editor.
If you think GoogleDocs would be better and can set it up. I think we can happily migrate.
Want to test it?The following code snip is working beta. Needs DScript.nut to run.
Code:
############## DAutoTxtRepl ###########################
// We define this stuff globally here so not every script instance uses a copy. Modify to your liking.
ParseDone<-false
ModTable<-
{ //Standard is TexRep0, insert a number behind a model name to change it to TexRep#
//a $ will be replaced by the entrys in an array in the slot directly behind the model name: "Model$",["A","B] -> "ModelA","ModelB"
//a # will be replaced by the numbers x->y specified a slot behind the model name "Model_#",1.3 -> Model_1,Model_2,Model_3
//All three optional variants can be combined but must be in the order Array,Float,integer
//"#$Worstcase",["a","b],1.2,3 ->a1Worstcase,3,a2Worstcase,3,b1Worstcase,3,b2Worstcase,3
Pictures=["NVPictureFrame","QuaintMain","DL_Wpaint1","res_pntv","res_pnth]
PictureFrames=[]
Posters=[]
Bushes=["DBushR","DBushR2","DBushR3","DBushR4","DBushR5]
Branches=["5aLeaves","7aLeaves]
Barks=["#$Tree",["a","b],1.4,"1aTrunk","1aTrunkN","1bTrunkN","2aTrunk","2bTrunk","3aTrunk","DL_tabletrunk","TreeBoughtFarm","TreeTorB_01]
DLeaves=["1aTree",1,"1aLeaves","1bLeaves","2aTree",1,"2bLeaves","2bTree",1,"3aLeaves","3aTree",1,1,"3bLeaves","3bTree",1,"3bTreelod2",1,"3cTree",1,"4aLeaves","4aTree",1,"4bLeaves","4bLeavesLod2","4bTree",1], //removed some models
Book31=["DBook","DBookB] //Bind Cover ratio id 3:1
BookWithSide=["DBook2","DBookB2]
Banner=[]
Windows=["DWin1","DWin3","House07Win1","House07Win2]
DoubleWindows=[]
Doors=["beldoor2]
//If the Textures are in a SubTable the behind number indicates the max field that should be filled. So for example BookWithSide=[..,"MyBook(.bin)",1,..] would only get TexRepr0 and TexRepr1
//TODO: Does not work for 0
Buildings4R=["House05RTower",0,"House01R","House02R","House03R","House04R","House05R","House05Rb","House05RSingle","House06R]
Roof=[]
}
TexTable<-
{
//A number behind a Texture will replace the # with 1->i for integer and for example 18->32 for float numbers.
//While it doesn't matter if a user doesn't have the models in ModTable you should make sure that the ones here in TexTable are provided or standard.
Pictures=["Paint1","Paint#",18.32,"picnic","RipOff",11,"RipOff",13.16] //These require EPv2
PictureFrames=[]
Posters=[]
Bushes=["PlantDa_#",20]
Branches=["falbrch","leaves#",4,"branch#",8,"v_Abranch","v_Abranch2","v_asp","v_branch","v_bush","v_fir","v_mapleaf","v_mapleaf2","smtrbrch","sprbrch","vindec3]
Barks=["bark#256",6,"v_apbark","v_obark","v_mapbark","v_seqbark","v_vbrk","GBark]
DLeaves=["leaves#",4],
Book31=
{
"0":["Book#",14],
"2":["DPage2Text],
"3":["DBindBlack","DBindBlue","DBindGreen","DBindRed","DBindYel],
}
BookWithSide=
{
KeepIndex="01", //string with #field names which should share the same randomed index both arrays must have the same size.
"0":["Book#-0",13],
"1":["Book#-1",13],
"2":["DPage2Text],
"3":["DBindBlack","DBindBlue","DBindGreen","DBindRed","DBindYel],
}
Windows=[]
Banner=["banner#",6,"banner8","banstar",3]
DoubleWindows=[]
Doors=[]
Buildings4R=
{
"0":["fam\\HQCity\\#_wall",24]
"1":["fam\\HQCity\\#_wall",24]
"2":["fam\\HQCity\\#_wall",24]
"3":["fam\\HQCity\\#_wall",24]
}
Roof=["roof","rooftile]
}
class DAutoTxtRepl extends DBaseTrap
#########################################
{
// ["NVPictureFrame","DBushR","DBushR2","DBushR3","DBushR4","DBushR5]
DefOn="+TurnOn+test";
function DChangeTxtRepl(texarray,field=0,i=-1,obj=false,path="obj\\txt16\\")
{
if (!obj)
obj=self
if (i==-1) //If same index is desired
i=Data.RandInt(0,texarray.len()-1)
local tex = texarray
if (startswith(tex,"fam\\"))
{path=""}
Property.Add(obj,"OTxtRepr"+field)
if (!(DGetParam(GetClassName()+"Lock",false)&&Property.Get(obj,"OTxtRepr"+field)!="")) //Should work without !=, Archetype definitions will be kept.
Property.SetSimple(obj,"OTxtRepr"+field, path+tex)
return i
}
function DParseTexArray(texarray)
{
local rem=[]
foreach (i,tv in texarray)
{
if (this=="ModTable"&&typeof(tv)=="string")
{
texarray=tv.tolower()
continue
}
if (typeof(tv)=="array")
{
local tname=split(texarray[i-1],"$")
foreach (idx,char in tv)
{
char=char.tolower()
if (tname.len()>1)
texarray.append(tname[0]+char+tname[1])
else
texarray.append(tname[0]+char)
if (typeof(texarray[i+1])=="integer"||typeof(texarray[i+1])=="float") //Will parse numbers separetly later
{
texarray.append(texarray[i+1])
if (typeof(texarray[i+2])=="integer") //Will parse numbers separetly later "#$Worstcase",["a","b","c],2.4,2
{
//print
texarray.append(texarray[i+2])
if (idx==tv.len()-1)
{
rem.append(i+2) //trash 1st generation
}
}
if (idx==0) //float XOR int trash
rem.append(i+1)
}
}
rem.append(i) //trash array and original
rem.append(i-1)
continue
}
local j=1
local ModInt=false
local noarbefore = (i==0||typeof(texarray[i-1])!="array")
if (typeof(tv)=="float"&&noarbefore)
{
tv=split(tv.tostring(),".")
j=tv[0].tointeger()
tv=tv[1].tointeger()
ModInt=true
}
if (typeof(tv)=="integer"&&(this=="TexTable"||ModInt)) //don't want to Parse for example Model-Leaves[1aTree,1]
{
local x=1
if (!noarbefore)
{
x=2
}
else
{
rem.append(i-x)
rem.append(i)
}
local tname=split(texarray[i-x],"#")
for (j;j<=tv;j++)
{
if (tname.len()>1)
texarray.append(tname[0]+j+tname[1])
else
texarray.append(tname[0]+j)
if (typeof(texarray[i+1])=="integer") //ModTable Beds=["Bed#",1.12,2] Parsing and a Field specified
{
texarray.append(texarray[i+1])
if (j==tv) //trash 2nd generation
{
rem.append(i+1)
}
}
}
}
}
//Trash preparsed entrys
rem.sort()
for (local r=rem.len()-1;r>=0;r--)
{
texarray.remove(rem[r])
}
// Print result for control
foreach (i,tv in texarray)
{
print(texarray+"["+i+]="+tv)
}
return texarray
}
############################################
function DoOn(DN) //TexTable={k=v[index i=tv] }
{
//Parse TexTablefor easier random use
if (!::ParseDone) //needs only be done once per Session
{
::ParseDone=true
foreach (k,v in TexTable)
{
if (typeof(v)=="array")
{
DParseTexArray.call("TexTable",v)
}
else //another table TexTable={ k= v={ k2=v2[index i=tv] } }
{
foreach (v2 in v)
{
if (typeof(v2)!="array") //KeepIndex. THIS IS THE PARSER
continue
DParseTexArray.call("TexTable",v2)
}
}
}
foreach (k,v in ModTable)
DParseTexArray.call("ModTable",v)
}
########### Actual Selection
type=DGetParam("DAutoTxtReplType",false,DN)
if (!type)
{//DetectionMode
local m = Property.Get(self,"ModelName").tolower()
foreach (k,v in ModTable)
{
local idx=v.find(m)
if (idx!=null)
{
//Check if custom tex field is specified.
local f = 0
if (!(idx==v.len()-1)&&typeof(v[idx+1])=="integer") //if its the last entry v[idx+1] would throw an error.
{
f = v[idx+1]
}
//Get Texture from a Array[]
if (typeof(TexTable[k])=="array")
{
DChangeTxtRepl(TexTable[k],f)
}
else //Get Textures from sub table like BookWithSide
{
local KeepIndex=["]
if ("KeepIndex" in TexTable[k])
{
KeepIndex=[TexTable[k]["KeepIndex],-1]
}
foreach (field, tv in TexTable[k]) //TexTable={ k=TexTbl[k]={ field=tv[...] } }
{
//TODO: Does not work for 0
if (typeof(tv)!="array"||f>0&&field.tointeger()>f) // KeepIndex case OR not all Fields should be used
continue
if (KeepIndex[0].find(field)!=null)
KeepIndex[1]=DChangeTxtRepl(tv,field,KeepIndex[1])
else
DChangeTxtRepl(tv,field)
}
}
}
//else
//That's wrong here print("DAutoTxtRepl ERROR: Didn't find a match for Shape ModelName "+m+". On Object "+self+. "Specify DAutoTxtReplType")
}
}
else
{
DChangeTxtRepl(TexTable[type],DGetParam("DAutoTxtReplField",0,DN))
}
/*For demo video
if (IsEditor()==2)
SetOneShotTimer("Change",1.5)
}
function OnTimer()
{
DoOn(userparams())
}
//*/
function constructor()
{
local DN=userparams()
local Mode = DGetParam("DAutoTxtReplMode",1,DN)
local Exe = IsEditor()
// 0 will only work when TurnedOn (standard Trap behavior) Default: TurnOn and script_test ObjID
// 1 (Default) Not automatically in game.exe
// 2 Everytime. PRO: Works on in game.exe created objects CONTRA: Also executes after save game loads. Consider DAutoTxtReplCount=1 (TODO: Check if compatible with BaseTrapConstructor) or (TODO:) No Overwrite option.
if (Mode!=0&&!(Exe+Mode==1))
DoOn(DN)
}
}
LarryG on 5/12/2017 at 23:49
This may be of use to you.
(
https://www.adrive.com/public/47SAC4/NewArt.zip) New Art package
> NewArt <
> Overview <
This package includes 128 painting objects based on images downloaded from
Olga's Gallery ((
http://www.abcgallery.com/)) and raw frame textures downloaded
from CG Textures ((
http://www.cgtextures.com/)) and then edited and adapted to
work within T2. The picture objects are based on the original T2 picture
objects with new art and frame textures applied.
Olga's Terms of use are simple and to the point:
Images from Olga's Gallery are made available for limited non-commercial,
educational, and personal use only, or for fair use as defined in the United
States copyright laws. Users must, however, cite the source of the image as
they would material from any printed work, and the citations should include
the URL "www.abcgallery.com."
CG Textures provides the following statement of restricted use:
Use of the Textures is only allowed under one or more of the following conditions:
- Private or commercial use
- Use in 2D or 3D computer graphics, movies and printed media
- Incorporation in computer games, 3D models
- Selling 3D models bundled with modified versions of the textures, when the
texture is customized for the 3D model
It is NOT permitted to:
- Sell or distribute any of these textures in an unmodified form, or where the
derived product you are selling or distributing is a Texture or a collection
of Textures. In other words: Do not sell or distribute any of these textures
(modified or not) by itself or in a texture pack!
- Interfere with the security or otherwise abuse, disrupt, place excessive loads
on, or attempt to gain unauthorized access to the CGTextures website or any
system resources or networks connected to this website.
- Stockpile images with the goal of making a local copy of all textures on the site.
- Using a special program (spider, leecher) or script to automatically download
all Textures on the CGTextures website. Users who try to mass download will be
banned from the website automatically.
This package is provided with these restrictions intact.
> Contents <
NewArt Readme.txt : This file
Index.pdf : A description of each painting included in this package.
Note that the T2 object used as the model for a new
painting is indicated by ">" in the list of compatible
T2 models.
PaintingArchetypes.pdf : Identification of achetype to object to texture in T2
..\NewArtSource : A sub-directory of .3ds files and individual palette
.gif files (higher quality color, but increases palette
use)
..\Obj : The sub-directory of the 128 picture .bin files
..\obj\Txt16 : The sub-directory with the 128 picture .gif files repaletized
to use only 10 palettes, together with 44 .gif frame textures