using System; using System.Globalization; using System.Windows.Forms; using CodeWalker.GameFiles; using SharpDX; namespace CodeWalker.Project.Panels { public partial class EditYtypArchetypePanel : ProjectPanel { public ProjectForm ProjectForm; private bool populatingui; public EditYtypArchetypePanel(ProjectForm owner) { InitializeComponent(); ProjectForm = owner; } public Archetype CurrentArchetype { get; set; } private void EditYtypArchetypePanel_Load(object sender, EventArgs e) { AssetTypeComboBox.Items.AddRange(Enum.GetNames(typeof(rage__fwArchetypeDef__eAssetType))); } public void SetArchetype(Archetype archetype) { CurrentArchetype = archetype; Tag = archetype; UpdateFormTitle(); UpdateControls(); } private void UpdateFormTitle() { Text = CurrentArchetype?.Name ?? "Edit Archetype"; } private void UpdateControls() { if (CurrentArchetype != null) { ArchetypeDeleteButton.Enabled = ProjectForm.YtypExistsInProject(CurrentArchetype.Ytyp); ArchetypeNameTextBox.Text = CurrentArchetype.Name; AssetNameTextBox.Text = CurrentArchetype.AssetName; LodDistNumericUpDown.Value = (decimal)CurrentArchetype._BaseArchetypeDef.lodDist; HDTextureDistNumericUpDown.Value = (decimal)CurrentArchetype._BaseArchetypeDef.hdTextureDist; SpecialAttributeNumericUpDown.Value = CurrentArchetype._BaseArchetypeDef.specialAttribute; ArchetypeFlagsTextBox.Text = CurrentArchetype._BaseArchetypeDef.flags.ToString(); TextureDictTextBox.Text = CurrentArchetype._BaseArchetypeDef.textureDictionary.ToCleanString(); ClipDictionaryTextBox.Text = CurrentArchetype._BaseArchetypeDef.clipDictionary.ToCleanString(); PhysicsDictionaryTextBox.Text = CurrentArchetype._BaseArchetypeDef.physicsDictionary.ToCleanString(); AssetTypeComboBox.Text = CurrentArchetype._BaseArchetypeDef.assetType.ToString(); BBMinTextBox.Text = FloatUtil.GetVector3String(CurrentArchetype._BaseArchetypeDef.bbMin); BBMaxTextBox.Text = FloatUtil.GetVector3String(CurrentArchetype._BaseArchetypeDef.bbMax); BSCenterTextBox.Text = FloatUtil.GetVector3String(CurrentArchetype._BaseArchetypeDef.bsCentre); BSRadiusTextBox.Text = CurrentArchetype._BaseArchetypeDef.bsRadius.ToString(CultureInfo.InvariantCulture); if (CurrentArchetype is MloArchetype MloArchetype) { if (!TabControl.TabPages.Contains(MloArchetypeTabPage)) { TabControl.TabPages.Add(MloArchetypeTabPage); } //MloInstanceData mloinstance = ProjectForm.TryGetMloInstance(MloArchetype); //nothing to see here right now } else TabControl.TabPages.Remove(MloArchetypeTabPage); if (CurrentArchetype is TimeArchetype TimeArchetype) { if (!TabControl.TabPages.Contains(TimeArchetypeTabPage)) { TabControl.TabPages.Add(TimeArchetypeTabPage); } TimeFlagsTextBox.Text = TimeArchetype.TimeFlags.ToString(); } else TabControl.TabPages.Remove(TimeArchetypeTabPage); } } private void ArchetypeFlagsTextBox_TextChanged(object sender, EventArgs e) { if (populatingui) return; if (CurrentArchetype == null) return; uint flags = 0; uint.TryParse(ArchetypeFlagsTextBox.Text, out flags); populatingui = true; for (int i = 0; i < EntityFlagsCheckedListBox.Items.Count; i++) { var c = ((flags & (1u << i)) > 0); EntityFlagsCheckedListBox.SetItemCheckState(i, c ? CheckState.Checked : CheckState.Unchecked); } populatingui = false; lock (ProjectForm.ProjectSyncRoot) { if (CurrentArchetype._BaseArchetypeDef.flags != flags) { CurrentArchetype._BaseArchetypeDef.flags = flags; ProjectForm.SetYtypHasChanged(true); } } } private void ArchetypeFlagsCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e) { if (populatingui) return; if (CurrentArchetype == null) return; uint flags = 0; for (int i = 0; i < EntityFlagsCheckedListBox.Items.Count; i++) { if (e.Index == i) { if (e.NewValue == CheckState.Checked) { flags += (uint)(1 << i); } } else { if (EntityFlagsCheckedListBox.GetItemChecked(i)) { flags += (uint)(1 << i); } } } populatingui = true; ArchetypeFlagsTextBox.Text = flags.ToString(); populatingui = false; lock (ProjectForm.ProjectSyncRoot) { if (CurrentArchetype._BaseArchetypeDef.flags != flags) { CurrentArchetype._BaseArchetypeDef.flags = flags; ProjectForm.SetYtypHasChanged(true); } } } private void TextureDictTextBox_TextChanged(object sender, EventArgs e) { // Check that the form is not null before locking... if (ProjectForm == null) return; lock (ProjectForm.ProjectSyncRoot) { // Embedded... if (TextureDictTextBox.Text == ArchetypeNameTextBox.Text) { TextureDictHashLabel.Text = "Embedded"; CurrentArchetype._BaseArchetypeDef.textureDictionary = CurrentArchetype._BaseArchetypeDef.name; return; } var hash = 0u; if (!uint.TryParse(TextureDictTextBox.Text, out hash))//don't re-hash hashes { hash = JenkHash.GenHash(TextureDictTextBox.Text); } if (CurrentArchetype._BaseArchetypeDef.textureDictionary != hash) { var ytd = ProjectForm.GameFileCache.GetYtd(hash); if (ytd == null) { TextureDictHashLabel.Text = "Hash: " + hash.ToString() + " (invalid)"; ProjectForm.SetYtypHasChanged(true); return; } CurrentArchetype._BaseArchetypeDef.textureDictionary = hash; ProjectForm.SetYtypHasChanged(true); } TextureDictHashLabel.Text = "Hash: " + hash.ToString(); } } private void PhysicsDictionaryTextBox_TextChanged(object sender, EventArgs e) { lock (ProjectForm.ProjectSyncRoot) { if (ProjectForm == null) { return; } // Embedded... if (PhysicsDictionaryTextBox.Text == ArchetypeNameTextBox.Text) { PhysicsDictHashLabel.Text = "Embedded"; CurrentArchetype._BaseArchetypeDef.physicsDictionary = CurrentArchetype._BaseArchetypeDef.name; return; } var hash = 0u; if (!uint.TryParse(PhysicsDictionaryTextBox.Text, out hash))//don't re-hash hashes { hash = JenkHash.GenHash(PhysicsDictionaryTextBox.Text); } if (CurrentArchetype._BaseArchetypeDef.physicsDictionary != hash) { var ytd = ProjectForm.GameFileCache.GetYbn(hash); if (ytd == null) { PhysicsDictHashLabel.Text = "Hash: " + hash.ToString() + " (invalid)"; ProjectForm.SetYtypHasChanged(true); return; } CurrentArchetype._BaseArchetypeDef.physicsDictionary = hash; ProjectForm.SetYtypHasChanged(true); } PhysicsDictHashLabel.Text = "Hash: " + hash.ToString(); } } private void ArchetypeNameTextBox_TextChanged(object sender, EventArgs e) { var hash = 0u; if (!uint.TryParse(ArchetypeNameTextBox.Text, out hash))//don't re-hash hashes { hash = JenkHash.GenHash(ArchetypeNameTextBox.Text); } if (CurrentArchetype._BaseArchetypeDef.name != hash) { CurrentArchetype._BaseArchetypeDef.name = hash; UpdateFormTitle(); TreeNode tn = ProjectForm.ProjectExplorer?.FindArchetypeTreeNode(CurrentArchetype); if (tn != null) tn.Text = ArchetypeNameTextBox.Text ?? "0"; // using the text box text because the name may not be in the gfc. ProjectForm.SetYtypHasChanged(true); } } private void AssetNameTextBox_TextChanged(object sender, EventArgs e) { var hash = 0u; if (!uint.TryParse(AssetNameTextBox.Text, out hash))//don't re-hash hashes { hash = JenkHash.GenHash(AssetNameTextBox.Text); } if (CurrentArchetype._BaseArchetypeDef.assetName != hash) { CurrentArchetype._BaseArchetypeDef.assetName = hash; ProjectForm.SetYtypHasChanged(true); } } private void ClipDictionaryTextBox_TextChanged(object sender, EventArgs e) { var hash = 0u; if (!uint.TryParse(ClipDictionaryTextBox.Text, out hash))//don't re-hash hashes { hash = JenkHash.GenHash(ClipDictionaryTextBox.Text); } if (CurrentArchetype._BaseArchetypeDef.clipDictionary != hash) { CurrentArchetype._BaseArchetypeDef.clipDictionary = hash; ProjectForm.SetYtypHasChanged(true); } } private void LodDistNumericUpDown_ValueChanged(object sender, EventArgs e) { var loddist = (float)LodDistNumericUpDown.Value; if (!MathUtil.NearEqual(loddist, CurrentArchetype._BaseArchetypeDef.lodDist)) { CurrentArchetype._BaseArchetypeDef.lodDist = loddist; ProjectForm.SetYtypHasChanged(true); } } private void HDTextureDistNumericUpDown_ValueChanged(object sender, EventArgs e) { var hddist = (float)HDTextureDistNumericUpDown.Value; if (!MathUtil.NearEqual(hddist, CurrentArchetype._BaseArchetypeDef.hdTextureDist)) { CurrentArchetype._BaseArchetypeDef.hdTextureDist = hddist; ProjectForm.SetYtypHasChanged(true); } } private void SpecialAttributeNumericUpDown_ValueChanged(object sender, EventArgs e) { var att = (uint)SpecialAttributeNumericUpDown.Value; if (CurrentArchetype._BaseArchetypeDef.specialAttribute != att) { CurrentArchetype._BaseArchetypeDef.specialAttribute = att; ProjectForm.SetYtypHasChanged(true); } } private void BBMinTextBox_TextChanged(object sender, EventArgs e) { Vector3 min = FloatUtil.ParseVector3String(BBMinTextBox.Text); if (CurrentArchetype._BaseArchetypeDef.bbMin != min) { CurrentArchetype._BaseArchetypeDef.bbMin = min; ProjectForm.SetYtypHasChanged(true); } } private void BBMaxTextBox_TextChanged(object sender, EventArgs e) { Vector3 max = FloatUtil.ParseVector3String(BBMaxTextBox.Text); if (CurrentArchetype._BaseArchetypeDef.bbMax != max) { CurrentArchetype._BaseArchetypeDef.bbMax = max; ProjectForm.SetYtypHasChanged(true); } } private void BSCenterTextBox_TextChanged(object sender, EventArgs e) { Vector3 c = FloatUtil.ParseVector3String(BSCenterTextBox.Text); if (CurrentArchetype._BaseArchetypeDef.bsCentre != c) { CurrentArchetype._BaseArchetypeDef.bsCentre = c; ProjectForm.SetYtypHasChanged(true); } } private void BSRadiusTextBox_TextChanged(object sender, EventArgs e) { if (float.TryParse(BSRadiusTextBox.Text, out float f)) { if (!MathUtil.NearEqual(CurrentArchetype._BaseArchetypeDef.bsRadius, f)) { CurrentArchetype._BaseArchetypeDef.bsRadius = f; ProjectForm.SetYtypHasChanged(true); } } else { CurrentArchetype._BaseArchetypeDef.bsRadius = 0f; ProjectForm.SetYtypHasChanged(true); } } private void DeleteArchetypeButton_Click(object sender, EventArgs e) { ProjectForm.SetProjectItem(CurrentArchetype); ProjectForm.DeleteArchetype(); } private void TimeFlagsTextBox_TextChanged(object sender, EventArgs e) { if (populatingui) return; if (CurrentArchetype == null) return; if (CurrentArchetype is TimeArchetype TimeArchetype) { uint flags = 0; uint.TryParse(TimeFlagsTextBox.Text, out flags); populatingui = true; for (int i = 0; i < TimeFlagsCheckedListBox.Items.Count; i++) { var c = ((flags & (1u << i)) > 0); TimeFlagsCheckedListBox.SetItemCheckState(i, c ? CheckState.Checked : CheckState.Unchecked); } populatingui = false; lock (ProjectForm.ProjectSyncRoot) { if (TimeArchetype.TimeFlags != flags) { TimeArchetype.SetTimeFlags(flags); ProjectForm.SetYtypHasChanged(true); } } } } private void TimeFlagsCheckedListBox_ItemCheck(object sender, ItemCheckEventArgs e) { if (populatingui) return; if (CurrentArchetype == null) return; if (CurrentArchetype is TimeArchetype TimeArchetype) { uint flags = 0; for (int i = 0; i < TimeFlagsCheckedListBox.Items.Count; i++) { if (e.Index == i) { if (e.NewValue == CheckState.Checked) { flags += (uint)(1 << i); } } else { if (TimeFlagsCheckedListBox.GetItemChecked(i)) { flags += (uint)(1 << i); } } } populatingui = true; TimeFlagsTextBox.Text = flags.ToString(); populatingui = false; lock (ProjectForm.ProjectSyncRoot) { if (TimeArchetype.TimeFlags != flags) { TimeArchetype.SetTimeFlags(flags); ProjectForm.SetYtypHasChanged(true); } } } } } }