Skip to content
This repository has been archived by the owner on Feb 14, 2025. It is now read-only.

Commit

Permalink
Merge pull request #98 from Kamzik123/master
Browse files Browse the repository at this point in the history
Added option to duplicate cutscene assets
  • Loading branch information
Greavesy1899 authored Jul 19, 2024
2 parents 73899b0 + 74bd2fd commit 9b80325
Show file tree
Hide file tree
Showing 15 changed files with 653 additions and 157 deletions.
232 changes: 135 additions & 97 deletions Mafia2Libs/Forms/CutsceneEditor.Designer.cs

Large diffs are not rendered by default.

313 changes: 305 additions & 8 deletions Mafia2Libs/Forms/CutsceneEditor.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
using Core.IO;
using ResourceTypes.Cutscene;
using ResourceTypes.Cutscene.AnimEntities;
using System;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Utils.Helpers;
using Utils.Extensions;
using Utils.Language;
using Utils.Settings;
using Utils.Logging;
using static ResourceTypes.Cutscene.CutsceneLoader;
using static ResourceTypes.Cutscene.CutsceneLoader.Cutscene;

namespace Mafia2Tool.Forms
{
Expand Down Expand Up @@ -52,7 +56,7 @@ private void AddCutsceneToTreeView(CutsceneLoader.Cutscene Cutscene)
for (int i = 0; i < Assets.entities.Length; i++)
{
var Asset = Assets.entities[i];
TreeNode AssetNode = new TreeNode(string.Format("Asset: {0}", i));
TreeNode AssetNode = new TreeNode(string.Format("{0}: {1}", Asset.GetType().Name, i));
AssetNode.Tag = Asset;

AssetsParent.Nodes.Add(AssetNode);
Expand All @@ -71,7 +75,7 @@ private void AddCutsceneToTreeView(CutsceneLoader.Cutscene Cutscene)
for (int i = 0; i < Assets.EntityDefinitions.Length; i++)
{
var Asset = Assets.EntityDefinitions[i];
TreeNode AssetNode = new TreeNode(string.Format("Asset: {0}", i));
TreeNode AssetNode = new TreeNode(string.Format("{0}: {1}", Asset.GetType().Name, i));
AssetNode.Tag = Asset;

AssetsParent.Nodes.Add(AssetNode);
Expand Down Expand Up @@ -127,10 +131,7 @@ private void Reload()

private void TreeView_Cutscene_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Action == TreeViewAction.ByKeyboard || e.Action == TreeViewAction.ByMouse)
{
PropertyGrid_Cutscene.SelectedObject = e.Node.Tag;
}
PropertyGrid_Cutscene.SelectedObject = e.Node.Tag;
}

private void PropertyGrid_Cutscene_PropertyChanged(object sender, PropertyValueChangedEventArgs e)
Expand Down Expand Up @@ -173,5 +174,301 @@ private void CutsceneEditor_Closing(object sender, FormClosingEventArgs e)
}
}
}

private void TreeViewContextMenu_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
ContextMenu_Import.Enabled = false;
ContextMenu_Export.Enabled = false;
ContextMenu_Duplicate.Enabled = false;

if (TreeView_Cutscene.SelectedNode.Tag is AnimEntityWrapper)
{
ContextMenu_Import.Enabled = true;
ContextMenu_Export.Enabled = true;
ContextMenu_Duplicate.Enabled = true;
}
else if (TreeView_Cutscene.SelectedNode.Tag is GCSData || TreeView_Cutscene.SelectedNode.Tag is SPDData)
{
ContextMenu_Import.Enabled = true;
ContextMenu_Export.Enabled = false;
ContextMenu_Duplicate.Enabled = false;
}
}

private void ContextMenu_Duplicate_Click(object sender, EventArgs e)
{
//Probably not the most optimal code, but cba to make better code

AnimEntityWrapper entity = (AnimEntityWrapper)TreeView_Cutscene.SelectedNode.Tag;
AnimEntityWrapper newEntity;
byte[] entityData = new byte[0];
byte[] animEntityData = new byte[0];

using (MemoryStream stream = new MemoryStream())
{
// Write Entity to the Stream
CutsceneEntityFactory.WriteAnimEntityToFile(stream, entity);
entityData = stream.ToArray();
}

using (MemoryStream EntityStream = new MemoryStream())
{
bool isBigEndian = false;
EntityStream.Write(entity.AnimEntityData.DataType, isBigEndian);
EntityStream.Write(0, isBigEndian);
entity.AnimEntityData.WriteToFile(EntityStream, isBigEndian);

animEntityData = EntityStream.ToArray();
}

using (MemoryStream Reader = new MemoryStream(entityData))
{
newEntity = CutsceneEntityFactory.ReadAnimEntityWrapperFromFile(entity.GetEntityType(), Reader);
}

using (MemoryStream stream = new MemoryStream(animEntityData))
{
newEntity.AnimEntityData.ReadFromFile(stream, false);
}

var cutscenes = OriginalFile.GetCutsceneLoader().Cutscenes;

for (int i = 0; i < cutscenes.Length; i++)
{
var cutscene = cutscenes[i];

if (cutscene.AssetContent.entities.Contains(entity))
{
var list = cutscene.AssetContent.entities.ToList();
var index = list.IndexOf(entity);
list.Insert(index + 1, newEntity);
cutscene.AssetContent.entities = list.ToArray();
Reload();
TreeView_Cutscene.Nodes[i].Nodes[0].Expand();
TreeView_Cutscene.SelectedNode = TreeView_Cutscene.Nodes[i].Nodes[0].Nodes[index];
Text = Language.GetString("$CUTSCENE_EDITOR") + "*";
bIsFileEdited = true;
return;
}
else if (cutscene.SoundContent.EntityDefinitions.Contains(entity))
{
var list = cutscene.SoundContent.EntityDefinitions.ToList();
var index = list.IndexOf(entity);
list.Insert(index + 1, newEntity);
cutscene.SoundContent.EntityDefinitions = list.ToArray();
Reload();
TreeView_Cutscene.Nodes[i].Nodes[1].Expand();
TreeView_Cutscene.SelectedNode = TreeView_Cutscene.Nodes[i].Nodes[1].Nodes[index];
Text = Language.GetString("$CUTSCENE_EDITOR") + "*";
bIsFileEdited = true;
return;
}
}
}

private void ContextMenu_Import_Click(object sender, EventArgs e)
{
GCSData gcsData = null;
SPDData spdData = null;
TreeNode gcsNode = null;
TreeNode spdNode = null;

if (TreeView_Cutscene.SelectedNode.Tag is GCSData)
{
gcsData = (GCSData)TreeView_Cutscene.SelectedNode.Tag;
gcsNode = TreeView_Cutscene.SelectedNode;
}
else if (TreeView_Cutscene.SelectedNode.Tag is SPDData)
{
spdData = (SPDData)TreeView_Cutscene.SelectedNode.Tag;
spdNode = TreeView_Cutscene.SelectedNode;
}
else if (TreeView_Cutscene.SelectedNode.Tag is AnimEntityWrapper)
{
if (TreeView_Cutscene.SelectedNode.Parent.Tag is GCSData)
{
gcsData = (GCSData)TreeView_Cutscene.SelectedNode.Parent.Tag;
gcsNode = TreeView_Cutscene.SelectedNode.Parent;
}
else if (TreeView_Cutscene.SelectedNode.Parent.Tag is SPDData)
{
spdData = (SPDData)TreeView_Cutscene.SelectedNode.Parent.Tag;
spdNode = TreeView_Cutscene.SelectedNode.Parent;
}
else
{
return;
}
}
else
{
return;
}

OpenFileDialog openFile = new();
openFile.InitialDirectory = OriginalFile.GetUnderlyingFileInfo().DirectoryName;
openFile.CheckFileExists = true;
openFile.CheckPathExists = true;
openFile.Title = "Import Cutscene entity data";
openFile.Filter = "Cutscene entity data|*.CutEntityData";
openFile.FileName = "Open file";

if (openFile.ShowDialog() == DialogResult.OK)
{
AnimEntityWrapper EntityWrapper = null;

using (MemoryStream ms = new(File.ReadAllBytes(openFile.FileName)))
{
int Size = ms.ReadInt32(false);
AnimEntityTypes AnimEntityType = (AnimEntityTypes)ms.ReadInt32(false);

using (MemoryStream Reader = new(ms.ReadBytes(Size - 4)))
{
EntityWrapper = CutsceneEntityFactory.ReadAnimEntityWrapperFromFile(AnimEntityType, Reader);
}

if (EntityWrapper == null)
{
return;
}

Size = ms.ReadInt32(false);

using (MemoryStream stream = new(ms.ReadBytes(Size)))
{
EntityWrapper.AnimEntityData.ReadFromFile(stream, false);
}
}

if (gcsData != null)
{
var entities = gcsData.entities.ToList();
entities.Add(EntityWrapper);
gcsData.entities = entities.ToArray();

var Asset = gcsData.entities[^1];
TreeNode AssetNode = new TreeNode(string.Format("{0}: {1}", Asset.GetType().Name, gcsData.entities.Length - 1));
AssetNode.Tag = Asset;

gcsNode.Nodes.Add(AssetNode);

TreeView_Cutscene.SelectedNode = AssetNode;
}
else if (spdData != null)
{
var entities = spdData.EntityDefinitions.ToList();
entities.Add(EntityWrapper);
spdData.EntityDefinitions = entities.ToArray();

var Asset = spdData.EntityDefinitions[^1];
TreeNode AssetNode = new TreeNode(string.Format("{0}: {1}", Asset.GetType().Name, spdData.EntityDefinitions.Length - 1));
AssetNode.Tag = Asset;

spdNode.Nodes.Add(AssetNode);

TreeView_Cutscene.SelectedNode = AssetNode;
}
}

Text = Language.GetString("$CUTSCENE_EDITOR") + "*";
bIsFileEdited = true;
}

private void ContextMenu_Export_Click(object sender, EventArgs e)
{
AnimEntityWrapper entity = (AnimEntityWrapper)TreeView_Cutscene.SelectedNode.Tag;
string name = TreeView_Cutscene.SelectedNode.Text.Replace(": ", "_");

SaveFileDialog saveFile = new();
saveFile.InitialDirectory = OriginalFile.GetUnderlyingFileInfo().DirectoryName;
saveFile.CheckFileExists = false;
saveFile.CheckPathExists = true;
saveFile.Title = "Export Cutscene entity data";
saveFile.Filter = "Cutscene entity data|*.CutEntityData";
saveFile.FileName = TreeView_Cutscene.SelectedNode.Parent.Parent.Text + "_" + name + ".CutEntityData";

if (saveFile.ShowDialog() == DialogResult.OK)
{
byte[] entityData = new byte[0];
byte[] animEntityData = new byte[0];
byte[] data = new byte[0];

using (MemoryStream stream = new())
{
stream.Write((int)entity.GetEntityType(), false);
CutsceneEntityFactory.WriteAnimEntityToFile(stream, entity);
entityData = stream.ToArray();
}

using (MemoryStream EntityStream = new())
{
bool isBigEndian = false;
entity.AnimEntityData.WriteToFile(EntityStream, isBigEndian);
animEntityData = EntityStream.ToArray();
}

using (MemoryStream dataStream = new())
{
dataStream.Write(entityData.Length, false);
dataStream.Write(entityData);
dataStream.Write(animEntityData.Length + 8, false);
dataStream.Write(entity.AnimEntityData.DataType, false);
dataStream.Write(animEntityData.Length + 8, false);
dataStream.Write(animEntityData);
data = dataStream.ToArray();
}

File.WriteAllBytes(saveFile.FileName, data);
}
}

private void ContextMenu_Delete_Click(object sender, EventArgs e)
{
GCSData gcsData = null;
SPDData spdData = null;
TreeNode gcsNode = null;
TreeNode spdNode = null;

if (TreeView_Cutscene.SelectedNode.Tag is AnimEntityWrapper)
{
if (TreeView_Cutscene.SelectedNode.Parent.Tag is GCSData)
{
gcsData = (GCSData)TreeView_Cutscene.SelectedNode.Parent.Tag;
gcsNode = TreeView_Cutscene.SelectedNode.Parent;
}
else if (TreeView_Cutscene.SelectedNode.Parent.Tag is SPDData)
{
spdData = (SPDData)TreeView_Cutscene.SelectedNode.Parent.Tag;
spdNode = TreeView_Cutscene.SelectedNode.Parent;
}
else
{
return;
}
}
else
{
return;
}

var entityNode = TreeView_Cutscene.SelectedNode;
AnimEntityWrapper entity = (AnimEntityWrapper)entityNode.Tag;
System.Collections.Generic.List<AnimEntityWrapper> entities = null;

if (gcsData != null)
{
entities = gcsData.entities.ToList();
entities.Remove(entity);
gcsData.entities = entities.ToArray();
gcsNode.Nodes.Remove(entityNode);
}
else if (spdData != null)
{
entities = spdData.EntityDefinitions.ToList();
entities.Remove(entity);
spdData.EntityDefinitions = entities.ToArray();
spdNode.Nodes.Remove(entityNode);
}
}
}
}
Loading

0 comments on commit 9b80325

Please sign in to comment.