Last active
October 31, 2019 03:51
-
-
Save Deeheks/0cf973ed7cab098ce298edcc57c62026 to your computer and use it in GitHub Desktop.
No need to create a new prop each time you want to reimport a decal. This is Boformer's Decal Script modified using parts of Ronyx RealTime mod code.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Script based off @boformer script called "Large Decals" | |
// https://gist.github.com/boformer/624eef5ffc8686cb5f12377f1be855f9 | |
// In addition to making the decal size and slope tolerance, | |
// this script looks for textures called decal_a.png or decal_d.png (etc) | |
// in the textures folder and replace them if they are found. | |
// Textures import code taken from the RealTime mod code (@Ronyx69). | |
// https://gist.github.com/ronyx69/9c0026648d26b1e1b09cb8ec8a831b17 | |
// Warning: Do not save vehicles after running this script without a game restart! | |
// Size of decal in meters - width and length | |
// (texture width and height will be stretched to match this) | |
var size = new Vector2(16.0f, 16.0f); | |
// Tiling amount | |
var tile = new Vector3(1.0f, 1.0f); | |
// Box mesh height, leave at a negative value to calculate automatically | |
var slopeTolerance = 5.0f; | |
Debug.Log("Script created a " + size.x + "x" + size.y + "m decal with a " + slopeTolerance + "m slope tolerance"); | |
if (slopeTolerance < 0) | |
{ | |
slopeTolerance = Mathf.Clamp((size.x + size.y) / 4f, 2f, 32f); | |
} | |
var scale = new Vector4(size.x, slopeTolerance, size.y, 0); | |
var tiling = new Vector4(tile.x, 0, tile.y, 0); | |
var asset = ToolsModifierControl.toolController.m_editPrefabInfo as PropInfo; | |
var mesh = asset.m_mesh; | |
var vertices = mesh.vertices; | |
var vertexArray = new Vector3[vertices.Length]; | |
vertices.CopyTo(vertexArray, 0); | |
for (int i = 0; i < vertices.Length; i++) | |
{ | |
if (vertexArray[i].x > 0) vertexArray[i].x = scale.x / 2f; else vertexArray[i].x = -scale.x / 2f; | |
if (vertexArray[i].y > 0) vertexArray[i].y = scale.y / 2f; else vertexArray[i].y = -scale.y / 2f; | |
if (vertexArray[i].z > 0) vertexArray[i].z = scale.z / 2f; else vertexArray[i].z = -scale.z / 2f; | |
} | |
mesh.vertices = vertexArray; | |
mesh.RecalculateBounds(); | |
asset.CalculateGeneratedInfo(); | |
asset.m_material.shader = Shader.Find("Custom/Props/Decal/Blend"); | |
asset.m_material.SetVector("_DecalSize", scale); | |
asset.m_material.SetVector("_DecalTiling", tiling); | |
asset.m_lodMesh = null; | |
asset.m_lodMaterial = null; | |
asset.m_lodRenderDistance = 1000; | |
typeof(PropInfo).GetField("m_UIEditorCategory", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(asset, "PropsResidentialGroundTiles"); | |
asset.m_createRuining = false; | |
asset.m_useColorVariations = false; | |
// Tells the asset editor to save _DecalSize and _DecalTiling shader properties | |
var vectorProps= Type.GetType("ColossalFramework.Packaging.ShaderUtil, ColossalManaged").GetField("vectorProps").GetValue(null) as string[]; | |
vectorProps[4]="_DecalSize"; | |
vectorProps[5]="_DecalTiling"; | |
// Textures must be placed in gamefolder/textures/ | |
var assetSource = "textures/"; | |
var assetname = "decal"; | |
var assetMaterial = asset.m_material; | |
var texturePath = " "; | |
Texture2D providedTexture=null; Color px; | |
// Bools | |
bool _d, _a, _c, _i, _n, _s, aci, xys, gamma; | |
_d = _a = _c = _i = _n = _s = aci = xys = gamma = false; | |
// Defaults | |
var defaultA = 1f; var defaultC = 1f; var defaultI = 0f; | |
var defaultX = 0.5f; var defaultY = 0.5f; var defaultS = 0f; | |
// _d (Diffuse) | |
Texture2D textureD; textureD = new Texture2D(1, 1); | |
texturePath = assetSource + assetname + "_d.png"; | |
if (File.Exists(texturePath)) { | |
textureD.LoadImage(File.ReadAllBytes(texturePath)); | |
_d=true; | |
} | |
if(_d) {assetMaterial.SetTexture("_MainTex", textureD); Debug.Log("Script replaced " + texturePath);} | |
// ACI START | |
// _a (Alpha) | |
Texture2D textureA; textureA = new Texture2D(1, 1); | |
texturePath = assetSource + assetname + "_a.png"; | |
if (File.Exists(texturePath)) { | |
textureA.LoadImage(File.ReadAllBytes(texturePath)); | |
providedTexture=textureA; _a=true; | |
Debug.Log("Script replaced " + texturePath); | |
} | |
// _c (Color) | |
Texture2D textureC; textureC = new Texture2D(1, 1); | |
texturePath = assetSource + assetname + "_c.png"; | |
if (File.Exists(texturePath)) { | |
textureC.LoadImage(File.ReadAllBytes(texturePath)); | |
providedTexture=textureC; _c=true; | |
Debug.Log("Script replaced " + texturePath); | |
} | |
// _i (Illumination) | |
Texture2D textureI; textureI = new Texture2D(1, 1); | |
texturePath = assetSource + assetname + "_i.png"; | |
if (File.Exists(texturePath)) { | |
textureI.LoadImage(File.ReadAllBytes(texturePath)); | |
providedTexture=textureI; _i=true; | |
Debug.Log("Script replaced " + texturePath); | |
} | |
// previous ACI | |
if(assetMaterial.GetTexture("_ACIMap")) | |
{ | |
var preACI = assetMaterial.GetTexture("_ACIMap") as Texture2D; | |
if(providedTexture) providedTexture = new Texture2D(providedTexture.width, providedTexture.height); | |
else providedTexture = new Texture2D(preACI.width, preACI.height); | |
if(preACI.name!="replaced") { | |
gamma = true; | |
} | |
providedTexture.SetPixels(preACI.GetPixels()); | |
providedTexture.anisoLevel = preACI.anisoLevel; | |
providedTexture.filterMode = preACI.filterMode; | |
providedTexture.wrapMode = preACI.wrapMode; | |
providedTexture.Apply(); | |
aci=true; GameObject.Destroy(preACI); | |
} | |
// ACI COMBINATION | |
if(providedTexture) | |
{ | |
for (int i = 0; i < textureA.width; i++) | |
{ | |
for (int j = 0; j < textureA.height; j++) | |
{ | |
px=providedTexture.GetPixel(i, j); | |
if(_a) px.r=textureA.GetPixel(i, j).r; else if(!aci) px.r=defaultA; | |
if(_c) px.g=textureC.GetPixel(i, j).g; else if(!aci) px.g=defaultC; | |
if(_i) px.b=textureI.GetPixel(i, j).b; else if(!aci) px.b=defaultI; | |
if(_a) px.r=Mathf.LinearToGammaSpace(1-px.r); | |
if(_c) px.g=Mathf.LinearToGammaSpace(1-px.g); | |
if(_i) px.b=Mathf.LinearToGammaSpace(px.b); | |
providedTexture.SetPixel(i, j, px); | |
} | |
} | |
providedTexture.Apply(); providedTexture.name="replaced"; | |
assetMaterial.SetTexture("_ACIMap", providedTexture); | |
} | |
// ACI END | |
// XYS START | |
providedTexture=null; gamma=false; | |
// _n (Normal) | |
Texture2D textureN; textureN = new Texture2D(1, 1); | |
texturePath = assetSource + assetname + "_n.png"; | |
if (File.Exists(texturePath)) { | |
textureN.LoadImage(File.ReadAllBytes(texturePath)); | |
providedTexture=textureN; _n=true; | |
Debug.Log("Script replaced " + texturePath); | |
} | |
// _s (Specular) | |
Texture2D textureS; textureS = new Texture2D(1, 1); | |
texturePath = assetSource + assetname + "_s.png"; | |
if (File.Exists(texturePath)) { | |
textureS.LoadImage(File.ReadAllBytes(texturePath)); | |
providedTexture=textureS; _s=true; | |
Debug.Log("Script replaced " + texturePath); | |
} | |
// previous XYS | |
if(assetMaterial.GetTexture("_XYSMap")) | |
{ | |
var preXYS = assetMaterial.GetTexture("_XYSMap") as Texture2D; | |
if(providedTexture) providedTexture = new Texture2D(providedTexture.width, providedTexture.height); | |
else providedTexture = new Texture2D(preXYS.width, preXYS.height); | |
if(preXYS.name!="replaced") { | |
gamma = true; | |
} | |
providedTexture.SetPixels(preXYS.GetPixels()); | |
providedTexture.anisoLevel = preXYS.anisoLevel; | |
providedTexture.filterMode = preXYS.filterMode; | |
providedTexture.wrapMode = preXYS.wrapMode; | |
providedTexture.Apply(); | |
xys=true; GameObject.Destroy(preXYS); | |
} | |
// XYS COMBINATION | |
if(providedTexture) | |
{ | |
for (int i = 0; i < providedTexture.width; i++) | |
{ | |
for (int j = 0; j < providedTexture.height; j++) | |
{ | |
px=providedTexture.GetPixel(i, j); | |
if(_n) { | |
px.r=textureN.GetPixel(i, j).r; | |
px.g=textureN.GetPixel(i, j).g; | |
} | |
else if(!xys) { | |
px.r=defaultX; | |
px.g=defaultY; | |
} | |
if(_s) px.b=textureS.GetPixel(i, j).b; else if (!xys) px.b=defaultS; | |
if(_n||gamma) px.r=Mathf.LinearToGammaSpace(px.r); | |
if(_n||gamma) px.g=Mathf.LinearToGammaSpace(px.g); | |
if(_s||gamma) px.b=Mathf.LinearToGammaSpace(1-px.b); | |
providedTexture.SetPixel(i, j, px); | |
} | |
} | |
providedTexture.Apply(); providedTexture.name="replaced"; | |
assetMaterial.SetTexture("_XYSMap", providedTexture); | |
} | |
// XYS END |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment