Before following this tutorial, I recommend you read my previous tutorial on how to dump and recompile Terraria here: http://www.unknowncheats.me/forum/ot...compiling.html
Dumping Data and Textures
In this smallish tutorial we'll cover dumping information from the game which may be useful for some hacks or third-party applications. This method will allow you to dump basically anything you want from the game.
Dumping Item Information
We'll start with dumping item information. To do this we can initialize items to their default base values using the Item classes function 'SetDefaults'. So, to ensure things are loaded far enough to get our data, at the bottom of Main.cs -> Initialize we'll add:
Code:
using (FileStream fStream = new FileStream("_itemlist.xml", FileMode.OpenOrCreate, FileAccess.Write))
{
XmlWriterSettings xmlSettings = new XmlWriterSettings();
xmlSettings.Indent = true;
XmlWriter xmlWriter = XmlWriter.Create(fStream, xmlSettings);
xmlWriter.WriteStartElement("Items");
for (int x = 0; x < Main.itemName.Length; x++)
{
Item i = new Item(); i.SetDefaults(x);
xmlWriter.WriteStartElement("item");
xmlWriter.WriteAttributeString("index", x.ToString());
xmlWriter.WriteAttributeString("name", i.name);
xmlWriter.WriteAttributeString("maxstack", i.maxStack.ToString());
xmlWriter.WriteEndElement();
}
xmlWriter.WriteEndElement();
xmlWriter.Flush();
xmlWriter.Close();
}
This will create an XML file named _itemlist.xml with all the items in it including their ID, name, and maxstack size. You can add other attributes as you see fit or need. You can also adjust the Player.cs class to allow full serialization but we wont get into that.
Dumping Textures
Since Terraria is written in XNA, the files are stored in special XNA formats. But we can reobtain the original texture and dump it back to PNG files. At the bottom of Main.cs we will add these two functions:
Code:
public void SaveTexture(String strPathFormat, Texture2D texture, Int32 clipcount)
{
using (FileStream fStream = new FileStream(strPathFormat, FileMode.OpenOrCreate, FileAccess.Write))
{
var tex = texture;
RenderTarget2D rt = new RenderTarget2D(this.GraphicsDevice, tex.Width, tex.Height / clipcount);
this.GraphicsDevice.SetRenderTarget(rt);
this.GraphicsDevice.Clear(Color.Transparent);
SpriteBatch sb = new SpriteBatch(this.GraphicsDevice);
sb.Begin(SpriteSortMode.Immediate, BlendState.NonPremultiplied);
sb.Draw(tex, new Vector2(0, 0), Color.White);
sb.End();
this.GraphicsDevice.SetRenderTarget(null);
rt.SaveAsPng(fStream, rt.Width, rt.Height);
fStream.Flush();
}
}
public void SaveTextureArray(String strPathFormat, Texture2D[] arr, Int32 clipcount)
{
for (int x = 0; x < arr.Length; x++)
{
using (FileStream fStream = new FileStream(String.Format(strPathFormat, x), FileMode.OpenOrCreate, FileAccess.Write))
{
var tex = arr[x];
RenderTarget2D rt = new RenderTarget2D(this.GraphicsDevice, tex.Width, tex.Height / clipcount);
this.GraphicsDevice.SetRenderTarget(rt);
this.GraphicsDevice.Clear(Color.Transparent);
SpriteBatch sb = new SpriteBatch(this.GraphicsDevice);
sb.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
sb.Draw(tex, new Vector2(0, 0), Color.White);
sb.End();
this.GraphicsDevice.SetRenderTarget(null);
rt.SaveAsPng(fStream, rt.Width, rt.Height);
fStream.Flush();
}
}
}
Next at the bottom of Main.cs -> Initialize we'll add the following to dump the base character style textures:
Code:
String[] strDirectories = new String[] { "Eyes", "Hair", "Hands", "Heads", "Pants", "Shirts", "Shoes", "UnderShirts" };
for (int x = 0; x < strDirectories.Length; x++)
Directory.CreateDirectory(strDirectories[x]);
// Eye Textures
SaveTexture("Eyes\\eyes.png", Main.playerEyesTexture, 19);
SaveTexture("Eyes\\eye_whites.png", Main.playerEyeWhitesTexture, 19);
// Hair Textures
SaveTextureArray("Hair\\hair_{0}.png", Main.playerHairTexture, 14);
SaveTextureArray("Hair\\hair_alt_{0}.png", Main.playerHairAltTexture, 14);
// Hand Textures
SaveTexture("Hands\\hands.png", Main.playerHandsTexture, 18);
SaveTexture("Hands\\hands2.png", Main.playerHands2Texture, 18);
// Head Textures
SaveTexture("Heads\\head.png", Main.playerHeadTexture, 20);
// Pants Textures
SaveTexture("Pants\\pants.png", Main.playerPantsTexture, 18);
// Shirt Textures
SaveTexture("Shirts\\shirt.png", Main.playerShirtTexture, 18);
// Shoe Textures
SaveTexture("Shoes\\shoes.png", Main.playerShoesTexture, 18);
// UnderShirt Textures
SaveTexture("UnderShirts\\undershirt.png", Main.playerUnderShirtTexture, 18);
SaveTexture("UnderShirts\\undershirt_2.png", Main.playerUnderShirt2Texture, 18);
The last param for the SaveTexture functions are the 'states' inside the texture. If you are unsure how many states a texture has set this to 1 and dump the texture. Then open the PNG file and count the amount of times the object is in the texture. For example this is the default hair texture:
This texture has 14 states, since the hair model appears 14 times. We only want the first one for a 'non-moving' model viewer such as a save game editor. So we tell the last param this has 14 states so it can properly clamp the image to the first states rect.
You can use these functions and methods to dump everything in Terraria that you wish to know.