From efd58b5044eeca70c7368664916bfba5779a1af9 Mon Sep 17 00:00:00 2001 From: dexy Date: Thu, 9 Jan 2020 00:44:35 +1100 Subject: [PATCH] Multiple selection improvements --- CodeWalker.csproj | 1 + Project/ProjectForm.cs | 8 +- Project/UndoStep.cs | 161 +++++-- Utils/MapUtils.cs | 846 ----------------------------------- World/MapSelection.cs | 974 +++++++++++++++++++++++++++++++++++++++++ World/WorldInfoForm.cs | 10 +- WorldForm.Designer.cs | 62 ++- WorldForm.cs | 489 ++++++--------------- WorldForm.resx | 116 ++--- 9 files changed, 1355 insertions(+), 1312 deletions(-) create mode 100644 World/MapSelection.cs diff --git a/CodeWalker.csproj b/CodeWalker.csproj index 6b36860..a142062 100644 --- a/CodeWalker.csproj +++ b/CodeWalker.csproj @@ -587,6 +587,7 @@ CutsceneForm.cs + Form diff --git a/Project/ProjectForm.cs b/Project/ProjectForm.cs index 194cd79..7892457 100644 --- a/Project/ProjectForm.cs +++ b/Project/ProjectForm.cs @@ -6237,7 +6237,7 @@ namespace CodeWalker.Project var grassbatch = sel.GrassBatch; var collvert = sel.CollisionVertex; var collpoly = sel.CollisionPoly; - var collbound = sel.CollisionBounds ?? collpoly?.Owner ?? collvert.Owner; + var collbound = sel.CollisionBounds ?? collpoly?.Owner ?? collvert?.Owner; var pathnode = sel.PathNode; var pathlink = sel.PathLink; var navpoly = sel.NavPoly; @@ -6404,17 +6404,17 @@ namespace CodeWalker.Project } catch { } } - public void OnWorldSelectionModified(MapSelection sel, List items) + public void OnWorldSelectionModified(MapSelection sel) { try { if (InvokeRequired) { - BeginInvoke(new Action(() => { OnWorldSelectionModified(sel, items); })); + BeginInvoke(new Action(() => { OnWorldSelectionModified(sel); })); } else { - if (sel.MultipleSelection) + if (sel.MultipleSelectionItems != null) { //TODO!! } diff --git a/Project/UndoStep.cs b/Project/UndoStep.cs index 4d0a744..710d5c8 100644 --- a/Project/UndoStep.cs +++ b/Project/UndoStep.cs @@ -21,44 +21,11 @@ namespace CodeWalker.Project } - - public class MultiPositionUndoStep : UndoStep + public abstract class MultiItemUndoStep : UndoStep { - private MapSelection Selection; - private MapSelection[] Items; - public Vector3 StartPosition { get; set; } - public Vector3 EndPosition { get; set; } + protected MapSelection Selection; - public MultiPositionUndoStep(MapSelection multiSel, MapSelection[] items, Vector3 startpos, WorldForm wf) - { - Selection = multiSel; - Items = items; - StartPosition = startpos; - EndPosition = multiSel.WidgetPosition; - - UpdateGraphics(wf); - } - - private void Update(WorldForm wf, ref MapSelection sel, Vector3 p, Vector3 o) - { - //update selection items positions for new widget position p - - Vector3 dp = p - o; - for (int i = 0; i < Items.Length; i++) - { - var refpos = Items[i].WidgetPosition; - Items[i].SetPosition(refpos + dp, false); - } - sel.MultipleSelectionCenter = p; //center used for widget pos... - - wf.SelectMulti(Items); - wf.SetWidgetPosition(p); - - UpdateGraphics(wf); - } - - - private void UpdateGraphics(WorldForm wf) + protected void UpdateGraphics(WorldForm wf) { Dictionary pathYnds = new Dictionary(); @@ -67,9 +34,9 @@ namespace CodeWalker.Project Dictionary scenarioYmts = new Dictionary(); Dictionary bounds = new Dictionary(); - if (Items != null) + if (Selection.MultipleSelectionItems != null) { - foreach (var item in Items) + foreach (var item in Selection.MultipleSelectionItems) { if (item.PathNode != null) { @@ -133,7 +100,35 @@ namespace CodeWalker.Project } + } + public class MultiPositionUndoStep : MultiItemUndoStep + { + public Vector3 StartPosition { get; set; } + public Vector3 EndPosition { get; set; } + public MultiPositionUndoStep(MapSelection multiSel, Vector3 startpos, WorldForm wf) + { + Selection = multiSel; + StartPosition = startpos; + EndPosition = multiSel.WidgetPosition; + + UpdateGraphics(wf); + } + + private void Update(WorldForm wf, ref MapSelection sel, Vector3 p, Vector3 o) + { + //update selection items positions for new widget position p + + Selection.MultipleSelectionCenter = o; + Selection.SetPosition(p, false); + + sel.MultipleSelectionCenter = p; //center used for widget pos... + + wf.SelectMulti(Selection.MultipleSelectionItems); + wf.SetWidgetPosition(p); + + UpdateGraphics(wf); + } public override void Undo(WorldForm wf, ref MapSelection sel) { @@ -147,7 +142,95 @@ namespace CodeWalker.Project public override string ToString() { - return (Items?.Length ?? 0).ToString() + " items: Position"; + return (Selection.MultipleSelectionItems?.Length ?? 0).ToString() + " items: Position"; + } + } + public class MultiRotationUndoStep : MultiItemUndoStep + { + public Quaternion StartRotation { get; set; } + public Quaternion EndRotation { get; set; } + + public MultiRotationUndoStep(MapSelection multiSel, Quaternion startrot, WorldForm wf) + { + Selection = multiSel; + StartRotation = startrot; + EndRotation = multiSel.WidgetRotation; + + UpdateGraphics(wf); + } + + private void Update(WorldForm wf, ref MapSelection sel, Quaternion r, Quaternion o) + { + //update selection items positions+rotations for new widget rotation r + + Selection.MultipleSelectionRotation = o; + Selection.SetRotation(r, false); + + sel.MultipleSelectionRotation = r; //used for widget rot... + + wf.SelectMulti(Selection.MultipleSelectionItems); + wf.SetWidgetRotation(r); + + UpdateGraphics(wf); + } + + public override void Undo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, StartRotation, EndRotation); + } + + public override void Redo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, EndRotation, StartRotation); + } + + public override string ToString() + { + return (Selection.MultipleSelectionItems?.Length ?? 0).ToString() + " items: Rotation"; + } + } + public class MultiScaleUndoStep : MultiItemUndoStep + { + public Vector3 StartScale { get; set; } + public Vector3 EndScale { get; set; } + + public MultiScaleUndoStep(MapSelection multiSel, Vector3 startpos, WorldForm wf) + { + Selection = multiSel; + StartScale = startpos; + EndScale = multiSel.WidgetScale; + + UpdateGraphics(wf); + } + + private void Update(WorldForm wf, ref MapSelection sel, Vector3 s, Vector3 o) + { + //update selection items positions for new widget position p + + Selection.MultipleSelectionScale = o; + Selection.SetScale(s, false); + + sel.MultipleSelectionScale = s; // used for widget scale... + + wf.SelectMulti(Selection.MultipleSelectionItems); + wf.SetWidgetScale(s); + + UpdateGraphics(wf); + } + + public override void Undo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, StartScale, EndScale); + } + + public override void Redo(WorldForm wf, ref MapSelection sel) + { + Update(wf, ref sel, EndScale, StartScale); + } + + public override string ToString() + { + return (Selection.MultipleSelectionItems?.Length ?? 0).ToString() + " items: Scale"; } } diff --git a/Utils/MapUtils.cs b/Utils/MapUtils.cs index df30331..5570f12 100644 --- a/Utils/MapUtils.cs +++ b/Utils/MapUtils.cs @@ -6,8 +6,6 @@ using System.Collections.Generic; using SharpDX; using SharpDX.Direct3D11; using CodeWalker.Utils; -using CodeWalker.World; -using CodeWalker.GameFiles; namespace CodeWalker { @@ -163,848 +161,4 @@ namespace CodeWalker - - - - - - [TypeConverter(typeof(ExpandableObjectConverter))] - public struct MapSelection - { - public YmapEntityDef EntityDef { get; set; } - public Archetype Archetype { get; set; } - public DrawableBase Drawable { get; set; } - public DrawableGeometry Geometry { get; set; } - public MetaWrapper EntityExtension { get; set; } - public MetaWrapper ArchetypeExtension { get; set; } - public YmapTimeCycleModifier TimeCycleModifier { get; set; } - public YmapCarGen CarGenerator { get; set; } - public YmapGrassInstanceBatch GrassBatch { get; set; } - public YmapDistantLODLights DistantLodLights { get; set; } - public YmapBoxOccluder BoxOccluder { get; set; } - public YmapOccludeModel OccludeModel { get; set; } - public YmapEntityDef MloEntityDef { get; set; } - public MCMloRoomDef MloRoomDef { get; set; } - public WaterQuad WaterQuad { get; set; } - public Bounds CollisionBounds { get; set; } - public BoundPolygon CollisionPoly { get; set; } - public BoundVertex CollisionVertex { get; set; } - public YnvPoly NavPoly { get; set; } - public YnvPoint NavPoint { get; set; } - public YnvPortal NavPortal { get; set; } - public YndNode PathNode { get; set; } - public YndLink PathLink { get; set; } - public TrainTrackNode TrainTrackNode { get; set; } - public ScenarioNode ScenarioNode { get; set; } - public MCScenarioChainingEdge ScenarioEdge { get; set; } - public AudioPlacement Audio { get; set; } - - public bool MultipleSelection { get; set; } - public Vector3 MultipleSelectionCenter { get; set; } - - public Vector3 BBOffset { get; set; } - public Quaternion BBOrientation { get; set; } - public BoundingBox AABB { get; set; } - public BoundingSphere BSphere { get; set; } - public int GeometryIndex { get; set; } - public Vector3 CamRel { get; set; } - public float HitDist { get; set; } - - - public bool HasValue - { - get - { - return (EntityDef != null) || - (Archetype != null) || - (Drawable != null) || - (Geometry != null) || - (EntityExtension != null) || - (ArchetypeExtension != null) || - (TimeCycleModifier != null) || - (CarGenerator != null) || - (GrassBatch != null) || - (WaterQuad != null) || - (CollisionBounds != null) || - (CollisionPoly != null) || - (CollisionVertex != null) || - (NavPoly != null) || - (NavPoint != null) || - (NavPortal != null) || - (PathNode != null) || - (TrainTrackNode != null) || - (DistantLodLights != null) || - (BoxOccluder != null) || - (OccludeModel != null) || - (MloEntityDef != null) || - (ScenarioNode != null) || - (Audio != null) || - (MloRoomDef != null); - } - } - - public bool HasHit - { - get { return (HitDist != float.MaxValue); } - } - - - public bool CheckForChanges(MapSelection mhit) - { - return (EntityDef != mhit.EntityDef) - || (Archetype != mhit.Archetype) - || (Drawable != mhit.Drawable) - || (TimeCycleModifier != mhit.TimeCycleModifier) - || (ArchetypeExtension != mhit.ArchetypeExtension) - || (EntityExtension != mhit.EntityExtension) - || (CarGenerator != mhit.CarGenerator) - || (MloEntityDef != mhit.MloEntityDef) - || (DistantLodLights != mhit.DistantLodLights) - || (GrassBatch != mhit.GrassBatch) - || (BoxOccluder != mhit.BoxOccluder) - || (OccludeModel != mhit.OccludeModel) - || (WaterQuad != mhit.WaterQuad) - || (CollisionBounds != mhit.CollisionBounds) - || (CollisionPoly != mhit.CollisionPoly) - || (CollisionVertex != mhit.CollisionVertex) - || (NavPoly != mhit.NavPoly) - || (NavPoint != mhit.NavPoint) - || (NavPortal != mhit.NavPortal) - || (PathNode != mhit.PathNode) - || (TrainTrackNode != mhit.TrainTrackNode) - || (ScenarioNode != mhit.ScenarioNode) - || (Audio != mhit.Audio) - || (MloRoomDef != mhit.MloRoomDef); - } - public bool CheckForChanges() - { - return (EntityDef != null) - || (Archetype != null) - || (Drawable != null) - || (TimeCycleModifier != null) - || (ArchetypeExtension != null) - || (EntityExtension != null) - || (CarGenerator != null) - || (MloEntityDef != null) - || (DistantLodLights != null) - || (GrassBatch != null) - || (BoxOccluder != null) - || (OccludeModel != null) - || (WaterQuad != null) - || (CollisionBounds != null) - || (CollisionPoly != null) - || (CollisionVertex != null) - || (NavPoly != null) - || (NavPoint != null) - || (NavPortal != null) - || (PathNode != null) - || (PathLink != null) - || (TrainTrackNode != null) - || (ScenarioNode != null) - || (Audio != null) - || (MloRoomDef != null); - } - - - public void Clear() - { - EntityDef = null; - Archetype = null; - Drawable = null; - Geometry = null; - EntityExtension = null; - ArchetypeExtension = null; - TimeCycleModifier = null; - CarGenerator = null; - GrassBatch = null; - BoxOccluder = null; - OccludeModel = null; - WaterQuad = null; - CollisionBounds = null; - CollisionPoly = null; - CollisionVertex = null; - NavPoly = null; - NavPoint = null; - NavPortal = null; - PathNode = null; - PathLink = null; - TrainTrackNode = null; - DistantLodLights = null; - MloEntityDef = null; - ScenarioNode = null; - ScenarioEdge = null; - Audio = null; - MultipleSelection = false; - AABB = new BoundingBox(); - GeometryIndex = 0; - CamRel = new Vector3(); - HitDist = float.MaxValue; - } - - public string GetNameString(string defval) - { - string name = defval; - if (MultipleSelection) - { - name = "Multiple items"; - } - else if (EntityDef != null) - { - name = EntityDef._CEntityDef.archetypeName.ToString(); - } - else if (Archetype != null) - { - name = Archetype.Hash.ToString(); - } - else if (TimeCycleModifier != null) - { - name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); - } - else if (CarGenerator != null) - { - name = CarGenerator.CCarGen.carModel.ToString(); - } - else if (DistantLodLights != null) - { - name = DistantLodLights.Ymap?.Name ?? ""; - } - else if (BoxOccluder != null) - { - name = "BoxOccluder " + (BoxOccluder.Ymap?.Name ?? "") + ": " + BoxOccluder.Index.ToString(); - } - else if (OccludeModel != null) - { - name = "OccludeModel " + (OccludeModel.Ymap?.Name ?? "") + ": " + OccludeModel.Index.ToString(); - } - else if (CollisionVertex != null) - { - name = "Vertex " + CollisionVertex.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty); - } - else if (CollisionPoly != null) - { - name = "Poly " + CollisionPoly.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty); - } - else if (CollisionBounds != null) - { - name = CollisionBounds.GetName(); - } - if (EntityExtension != null) - { - name = EntityExtension.Name; - } - if (ArchetypeExtension != null) - { - name = ArchetypeExtension.Name; - } - if (WaterQuad != null) - { - name = "WaterQuad " + WaterQuad.ToString(); - } - if (NavPoly != null) - { - name = "NavPoly " + NavPoly.ToString(); - } - if (NavPoint != null) - { - name = "NavPoint " + NavPoint.ToString(); - } - if (NavPortal != null) - { - name = "NavPortal " + NavPortal.ToString(); - } - if (PathNode != null) - { - name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString(); //+ FloatUtil.GetVector3String(PathNode.Position); - } - if (TrainTrackNode != null) - { - name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); - } - if (ScenarioNode != null) - { - name = ScenarioNode.ToString(); - } - if (Audio != null) - { - name = Audio.ShortTypeName + " " + Audio.GetNameString();// FloatUtil.GetVector3String(Audio.InnerPos); - } - if (MloRoomDef != null) - { - name = "MloRoomDef " + MloRoomDef.RoomName; - } - return name; - } - - public string GetFullNameString(string defval) - { - string name = defval; - if (MultipleSelection) - { - name = "Multiple items"; - } - else if (EntityDef != null) - { - name = EntityDef._CEntityDef.archetypeName.ToString(); - } - else if (Archetype != null) - { - name = Archetype.Hash.ToString(); - } - else if (CollisionVertex != null) - { - name = "Vertex " + CollisionVertex.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty); - } - else if (CollisionPoly != null) - { - name = "Poly " + CollisionPoly.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty); - } - else if (CollisionBounds != null) - { - name = CollisionBounds.GetName(); - } - if (Geometry != null) - { - name += " (" + GeometryIndex.ToString() + ")"; - } - if (TimeCycleModifier != null) - { - name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); - } - if (BoxOccluder != null) - { - name = "BoxOccluder " + (BoxOccluder.Ymap?.Name ?? "") + ": " + BoxOccluder.Index.ToString(); - } - if (OccludeModel != null) - { - name = "OccludeModel " + (OccludeModel.Ymap?.Name ?? "") + ": " + OccludeModel.Index.ToString(); - } - if (CarGenerator != null) - { - name = CarGenerator.NameString(); - } - if (EntityExtension != null) - { - name += ": " + EntityExtension.Name; - } - if (ArchetypeExtension != null) - { - name += ": " + ArchetypeExtension.Name; - } - if (WaterQuad != null) - { - name = "WaterQuad " + WaterQuad.ToString(); - } - if (NavPoly != null) - { - name = "NavPoly " + NavPoly.ToString(); - } - if (NavPoint != null) - { - name = "NavPoint " + NavPoint.ToString(); - } - if (NavPortal != null) - { - name = "NavPortal " + NavPortal.ToString(); - } - if (PathNode != null) - { - name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString();// + FloatUtil.GetVector3String(PathNode.Position); - } - if (TrainTrackNode != null) - { - name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); - } - if (ScenarioNode != null) - { - name = ScenarioNode.ToString(); - } - if (Audio != null) - { - name = Audio.ShortTypeName + " " + Audio.GetNameString();// + FloatUtil.GetVector3String(Audio.InnerPos); - } - if (MloRoomDef != null) - { - name = "MloRoomDef " + MloRoomDef.RoomName; - } - return name; - } - - - - public bool CanShowWidget - { - get - { - bool res = false; - - if (MultipleSelection) - { - res = true; - } - else if (EntityDef != null) - { - res = true; - } - else if (CarGenerator != null) - { - res = true; - } - else if (NavPoly != null) - { - res = true; - } - else if (CollisionVertex != null) - { - res = true; - } - else if (CollisionPoly != null) - { - res = true; - } - else if (CollisionBounds != null) - { - res = true; - } - else if (NavPoint != null) - { - res = true; - } - else if (NavPortal != null) - { - res = true; - } - else if (PathNode != null) - { - res = true; - } - else if (TrainTrackNode != null) - { - res = true; - } - else if (ScenarioNode != null) - { - res = true; - } - else if (Audio != null) - { - res = true; - } - return res; - } - } - public Vector3 WidgetPosition - { - get - { - if (MultipleSelection) - { - return MultipleSelectionCenter; - } - else if (EntityDef != null) - { - return EntityDef.WidgetPosition; - } - else if (CarGenerator != null) - { - return CarGenerator.Position; - } - else if (CollisionVertex != null) - { - return CollisionVertex.Position; - } - else if (CollisionPoly != null) - { - return CollisionPoly.Position; - } - else if (CollisionBounds != null) - { - return CollisionBounds.Position; - } - else if (NavPoly != null) - { - return NavPoly.Position; - } - else if (NavPoint != null) - { - return NavPoint.Position; - } - else if (NavPortal != null) - { - return NavPortal.Position; - } - else if (PathNode != null) - { - return PathNode.Position; - } - else if (TrainTrackNode != null) - { - return TrainTrackNode.Position; - } - else if (ScenarioNode != null) - { - return ScenarioNode.Position; - } - else if (Audio != null) - { - return Audio.InnerPos; - } - return Vector3.Zero; - } - } - public Quaternion WidgetRotation - { - get - { - if (MultipleSelection) - { - return Quaternion.Identity; - } - else if (EntityDef != null) - { - return EntityDef.WidgetOrientation; - } - else if (CarGenerator != null) - { - return CarGenerator.Orientation; - } - else if (CollisionVertex != null) - { - return Quaternion.Identity; - } - else if (CollisionPoly != null) - { - return CollisionPoly.Orientation; - } - else if (CollisionBounds != null) - { - return CollisionBounds.Orientation; - } - else if (NavPoly != null) - { - return Quaternion.Identity; - } - else if (NavPoint != null) - { - return NavPoint.Orientation; - } - else if (NavPortal != null) - { - return NavPortal.Orientation; - } - else if (PathNode != null) - { - return Quaternion.Identity; - } - else if (TrainTrackNode != null) - { - return Quaternion.Identity; - } - else if (ScenarioNode != null) - { - return ScenarioNode.Orientation; - } - else if (Audio != null) - { - return Audio.Orientation; - } - return Quaternion.Identity; - } - } - public WidgetAxis WidgetRotationAxes - { - get - { - if (MultipleSelection) - { - return WidgetAxis.XYZ; - } - else if (EntityDef != null) - { - return WidgetAxis.XYZ; - } - else if (CarGenerator != null) - { - return WidgetAxis.Z; - } - else if (CollisionVertex != null) - { - return WidgetAxis.None; - } - else if (CollisionPoly != null) - { - return WidgetAxis.XYZ; - } - else if (CollisionBounds != null) - { - return WidgetAxis.XYZ; - } - else if (NavPoly != null) - { - return WidgetAxis.XYZ; - } - else if (NavPoint != null) - { - return WidgetAxis.Z; - } - else if (NavPortal != null) - { - return WidgetAxis.Z; - } - else if (PathNode != null) - { - return WidgetAxis.None; - } - else if (TrainTrackNode != null) - { - return WidgetAxis.None; - } - else if (ScenarioNode != null) - { - return WidgetAxis.Z; - } - else if (Audio != null) - { - return WidgetAxis.Z; - } - return WidgetAxis.None; - } - } - public Vector3 WidgetScale - { - get - { - if (MultipleSelection) - { - return Vector3.One; - } - else if (EntityDef != null) - { - return EntityDef.Scale; - } - else if (CarGenerator != null) - { - return new Vector3(CarGenerator.CCarGen.perpendicularLength); - } - else if (CollisionVertex != null) - { - return Vector3.One; - } - else if (CollisionPoly != null) - { - return CollisionPoly.Scale; - } - else if (CollisionBounds != null) - { - return CollisionBounds.Scale; - } - else if (NavPoly != null) - { - return Vector3.One; - } - else if (NavPoint != null) - { - return Vector3.One; - } - else if (NavPortal != null) - { - return Vector3.One; - } - else if (PathNode != null) - { - return Vector3.One; - } - else if (TrainTrackNode != null) - { - return Vector3.One; - } - else if (ScenarioNode != null) - { - return Vector3.One; - } - else if (Audio != null) - { - return Vector3.One; - } - return Vector3.One; - } - } - public bool WidgetScaleLockXY - { - get - { - if (CollisionBounds != null) - { - return false; - } - if (CollisionPoly != null) - { - return false; - } - return true; - } - } - - - - public void SetPosition(Vector3 newpos, bool editPivot) - { - if (MultipleSelection) - { - //don't do anything here for multiselection - } - else if (EntityDef != null) - { - if (editPivot) - { - EntityDef.SetPivotPositionFromWidget(newpos); - } - else - { - EntityDef.SetPositionFromWidget(newpos); - } - } - else if (CarGenerator != null) - { - CarGenerator.SetPosition(newpos); - } - else if (PathNode != null) - { - PathNode.SetPosition(newpos); - } - else if (CollisionVertex != null) - { - CollisionVertex.Position = newpos; - } - else if (CollisionPoly != null) - { - CollisionPoly.Position = newpos; - } - else if (CollisionBounds != null) - { - CollisionBounds.Position = newpos; - } - else if (NavPoly != null) - { - NavPoly.SetPosition(newpos); - } - else if (NavPoint != null) - { - NavPoint.SetPosition(newpos); - } - else if (NavPortal != null) - { - NavPortal.SetPosition(newpos); - } - else if (TrainTrackNode != null) - { - TrainTrackNode.SetPosition(newpos); - } - else if (ScenarioNode != null) - { - ScenarioNode.SetPosition(newpos); - } - else if (Audio != null) - { - Audio.SetPosition(newpos); - } - - } - public void SetRotation(Quaternion newrot, Quaternion oldrot, bool editPivot) - { - if (EntityDef != null) - { - if (editPivot) - { - EntityDef.SetPivotOrientationFromWidget(newrot); - } - else - { - EntityDef.SetOrientationFromWidget(newrot); - } - } - else if (CarGenerator != null) - { - CarGenerator.SetOrientation(newrot); - } - else if (CollisionPoly != null) - { - CollisionPoly.Orientation = newrot; - } - else if (CollisionBounds != null) - { - CollisionBounds.Orientation = newrot; - } - else if (ScenarioNode != null) - { - ScenarioNode.SetOrientation(newrot); - } - else if (NavPoint != null) - { - NavPoint.SetOrientation(newrot); - } - else if (NavPortal != null) - { - NavPortal.SetOrientation(newrot); - } - else if (Audio != null) - { - Audio.SetOrientation(newrot); - } - } - public void SetScale(Vector3 newscale, Vector3 oldscale, bool editPivot) - { - if (EntityDef != null) - { - EntityDef.SetScale(newscale); - } - else if (CarGenerator != null) - { - CarGenerator.SetScale(newscale); - AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax); - } - else if (CollisionPoly != null) - { - CollisionPoly.Scale = newscale; - } - else if (CollisionBounds != null) - { - CollisionBounds.Scale = newscale; - } - } - - - public override string ToString() - { - return GetFullNameString("[Empty]"); - } - } - - public enum MapSelectionMode - { - None = 0, - Entity = 1, - EntityExtension = 2, - ArchetypeExtension = 3, - TimeCycleModifier = 4, - CarGenerator = 5, - Grass = 6, - WaterQuad = 7, - Collision = 8, - NavMesh = 9, - Path = 10, - TrainTrack = 11, - DistantLodLights = 12, - MloInstance = 13, - Scenario = 14, - PopZone = 15, - Audio = 16, - Occlusion = 17, - } - - - - - - - } \ No newline at end of file diff --git a/World/MapSelection.cs b/World/MapSelection.cs new file mode 100644 index 0000000..b392476 --- /dev/null +++ b/World/MapSelection.cs @@ -0,0 +1,974 @@ +using CodeWalker.GameFiles; +using CodeWalker.Project; +using CodeWalker.World; +using SharpDX; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CodeWalker +{ + + + + public enum MapSelectionMode + { + None = 0, + Entity = 1, + EntityExtension = 2, + ArchetypeExtension = 3, + TimeCycleModifier = 4, + CarGenerator = 5, + Grass = 6, + WaterQuad = 7, + Collision = 8, + NavMesh = 9, + Path = 10, + TrainTrack = 11, + DistantLodLights = 12, + MloInstance = 13, + Scenario = 14, + PopZone = 15, + Audio = 16, + Occlusion = 17, + } + + + + [TypeConverter(typeof(ExpandableObjectConverter))] + public struct MapSelection + { + public YmapEntityDef EntityDef { get; set; } + public Archetype Archetype { get; set; } + public DrawableBase Drawable { get; set; } + public DrawableGeometry Geometry { get; set; } + public MetaWrapper EntityExtension { get; set; } + public MetaWrapper ArchetypeExtension { get; set; } + public YmapTimeCycleModifier TimeCycleModifier { get; set; } + public YmapCarGen CarGenerator { get; set; } + public YmapGrassInstanceBatch GrassBatch { get; set; } + public YmapDistantLODLights DistantLodLights { get; set; } + public YmapBoxOccluder BoxOccluder { get; set; } + public YmapOccludeModel OccludeModel { get; set; } + public YmapEntityDef MloEntityDef { get; set; } + public MCMloRoomDef MloRoomDef { get; set; } + public WaterQuad WaterQuad { get; set; } + public Bounds CollisionBounds { get; set; } + public BoundPolygon CollisionPoly { get; set; } + public BoundVertex CollisionVertex { get; set; } + public YnvPoly NavPoly { get; set; } + public YnvPoint NavPoint { get; set; } + public YnvPortal NavPortal { get; set; } + public YndNode PathNode { get; set; } + public YndLink PathLink { get; set; } + public TrainTrackNode TrainTrackNode { get; set; } + public ScenarioNode ScenarioNode { get; set; } + public MCScenarioChainingEdge ScenarioEdge { get; set; } + public AudioPlacement Audio { get; set; } + + public MapSelection[] MultipleSelectionItems { get; set; } + public Vector3 MultipleSelectionCenter { get; set; } + public Quaternion MultipleSelectionRotation { get; set; } + public Vector3 MultipleSelectionScale { get; set; } + + public Vector3 BBOffset { get; set; } + public Quaternion BBOrientation { get; set; } + public BoundingBox AABB { get; set; } + public BoundingSphere BSphere { get; set; } + public int GeometryIndex { get; set; } + public Vector3 CamRel { get; set; } + public float HitDist { get; set; } + + + public bool HasValue + { + get + { + return (EntityDef != null) || + (Archetype != null) || + (Drawable != null) || + (Geometry != null) || + (EntityExtension != null) || + (ArchetypeExtension != null) || + (TimeCycleModifier != null) || + (CarGenerator != null) || + (GrassBatch != null) || + (WaterQuad != null) || + (CollisionBounds != null) || + (CollisionPoly != null) || + (CollisionVertex != null) || + (NavPoly != null) || + (NavPoint != null) || + (NavPortal != null) || + (PathNode != null) || + (TrainTrackNode != null) || + (DistantLodLights != null) || + (BoxOccluder != null) || + (OccludeModel != null) || + (MloEntityDef != null) || + (ScenarioNode != null) || + (Audio != null) || + (MloRoomDef != null); + } + } + + public bool HasHit + { + get { return (HitDist != float.MaxValue); } + } + + + public bool CheckForChanges(MapSelection mhit) + { + return (EntityDef != mhit.EntityDef) + || (Archetype != mhit.Archetype) + || (Drawable != mhit.Drawable) + || (TimeCycleModifier != mhit.TimeCycleModifier) + || (ArchetypeExtension != mhit.ArchetypeExtension) + || (EntityExtension != mhit.EntityExtension) + || (CarGenerator != mhit.CarGenerator) + || (MloEntityDef != mhit.MloEntityDef) + || (DistantLodLights != mhit.DistantLodLights) + || (GrassBatch != mhit.GrassBatch) + || (BoxOccluder != mhit.BoxOccluder) + || (OccludeModel != mhit.OccludeModel) + || (WaterQuad != mhit.WaterQuad) + || (CollisionBounds != mhit.CollisionBounds) + || (CollisionPoly != mhit.CollisionPoly) + || (CollisionVertex != mhit.CollisionVertex) + || (NavPoly != mhit.NavPoly) + || (NavPoint != mhit.NavPoint) + || (NavPortal != mhit.NavPortal) + || (PathNode != mhit.PathNode) + || (TrainTrackNode != mhit.TrainTrackNode) + || (ScenarioNode != mhit.ScenarioNode) + || (Audio != mhit.Audio) + || (MloRoomDef != mhit.MloRoomDef); + } + public bool CheckForChanges() + { + return (EntityDef != null) + || (Archetype != null) + || (Drawable != null) + || (TimeCycleModifier != null) + || (ArchetypeExtension != null) + || (EntityExtension != null) + || (CarGenerator != null) + || (MloEntityDef != null) + || (DistantLodLights != null) + || (GrassBatch != null) + || (BoxOccluder != null) + || (OccludeModel != null) + || (WaterQuad != null) + || (CollisionBounds != null) + || (CollisionPoly != null) + || (CollisionVertex != null) + || (NavPoly != null) + || (NavPoint != null) + || (NavPortal != null) + || (PathNode != null) + || (PathLink != null) + || (TrainTrackNode != null) + || (ScenarioNode != null) + || (Audio != null) + || (MloRoomDef != null); + } + + + public void Clear() + { + EntityDef = null; + Archetype = null; + Drawable = null; + Geometry = null; + EntityExtension = null; + ArchetypeExtension = null; + TimeCycleModifier = null; + CarGenerator = null; + GrassBatch = null; + BoxOccluder = null; + OccludeModel = null; + WaterQuad = null; + CollisionBounds = null; + CollisionPoly = null; + CollisionVertex = null; + NavPoly = null; + NavPoint = null; + NavPortal = null; + PathNode = null; + PathLink = null; + TrainTrackNode = null; + DistantLodLights = null; + MloEntityDef = null; + ScenarioNode = null; + ScenarioEdge = null; + Audio = null; + MultipleSelectionItems = null; + MultipleSelectionCenter = Vector3.Zero; + MultipleSelectionRotation = Quaternion.Identity; + MultipleSelectionScale = Vector3.One; + AABB = new BoundingBox(); + GeometryIndex = 0; + CamRel = Vector3.Zero; + HitDist = float.MaxValue; + } + + public string GetNameString(string defval) + { + string name = defval; + if (MultipleSelectionItems != null) + { + name = "Multiple items"; + } + else if (EntityDef != null) + { + name = EntityDef._CEntityDef.archetypeName.ToString(); + } + else if (Archetype != null) + { + name = Archetype.Hash.ToString(); + } + else if (TimeCycleModifier != null) + { + name = TimeCycleModifier.CTimeCycleModifier.name.ToString(); + } + else if (CarGenerator != null) + { + name = (CarGenerator.Ymap?.Name ?? "") + ": " + CarGenerator.NameString(); + } + else if (GrassBatch != null) + { + name = (GrassBatch.Ymap?.Name ?? "") + ": " + GrassBatch.Archetype?.Name ?? ""; + } + else if (DistantLodLights != null) + { + name = DistantLodLights.Ymap?.Name ?? ""; + } + else if (BoxOccluder != null) + { + name = "BoxOccluder " + (BoxOccluder.Ymap?.Name ?? "") + ": " + BoxOccluder.Index.ToString(); + } + else if (OccludeModel != null) + { + name = "OccludeModel " + (OccludeModel.Ymap?.Name ?? "") + ": " + OccludeModel.Index.ToString(); + } + else if (CollisionVertex != null) + { + name = "Vertex " + CollisionVertex.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty); + } + else if (CollisionPoly != null) + { + name = "Poly " + CollisionPoly.Index.ToString() + ((CollisionBounds != null) ? (": " + CollisionBounds.GetName()) : string.Empty); + } + else if (CollisionBounds != null) + { + name = CollisionBounds.GetName(); + } + else if (WaterQuad != null) + { + name = "WaterQuad " + WaterQuad.ToString(); + } + else if (NavPoly != null) + { + name = "NavPoly " + NavPoly.ToString(); + } + else if (NavPoint != null) + { + name = "NavPoint " + NavPoint.ToString(); + } + else if (NavPortal != null) + { + name = "NavPortal " + NavPortal.ToString(); + } + else if (PathNode != null) + { + name = "PathNode " + PathNode.AreaID.ToString() + "." + PathNode.NodeID.ToString(); //+ FloatUtil.GetVector3String(PathNode.Position); + } + else if (TrainTrackNode != null) + { + name = "TrainTrackNode " + FloatUtil.GetVector3String(TrainTrackNode.Position); + } + else if (ScenarioNode != null) + { + name = ScenarioNode.ToString(); + } + else if (Audio != null) + { + name = Audio.ShortTypeName + " " + Audio.GetNameString();// FloatUtil.GetVector3String(Audio.InnerPos); + } + if (MloRoomDef != null) + { + name = "MloRoomDef " + MloRoomDef.RoomName; + } + if (EntityExtension != null) + { + name += ": " + EntityExtension.Name; + } + if (ArchetypeExtension != null) + { + name += ": " + ArchetypeExtension.Name; + } + return name; + } + + public string GetFullNameString(string defval) + { + string name = GetNameString(defval); + if (Geometry != null) + { + name += " (" + GeometryIndex.ToString() + ")"; + } + return name; + } + + + public bool CanMarkUndo() + { + if (MultipleSelectionItems != null) return true; + if (EntityDef != null) return true; + if (CarGenerator != null) return true; + if (CollisionBounds != null) return true; + if (CollisionPoly != null) return true; + if (PathNode != null) return true; + //if (NavPoly != null) return true; + if (NavPoint != null) return true; + if (NavPortal != null) return true; + if (TrainTrackNode != null) return true; + if (ScenarioNode != null) return true; + if (Audio != null) return true; + return false; + } + public UndoStep CreateUndoStep(WidgetMode mode, Vector3 startPos, Quaternion startRot, Vector3 startScale, WorldForm wf, bool editPivot) + { + if (MultipleSelectionItems != null) + { + switch (mode) + { + case WidgetMode.Position: return new MultiPositionUndoStep(this, startPos, wf); + case WidgetMode.Rotation: return new MultiRotationUndoStep(this, startRot, wf); + case WidgetMode.Scale: return new MultiScaleUndoStep(this, startScale, wf); + } + } + else if (EntityDef != null) + { + if (editPivot) + { + switch (mode) + { + case WidgetMode.Position: return new EntityPivotPositionUndoStep(EntityDef, startPos); + case WidgetMode.Rotation: return new EntityPivotRotationUndoStep(EntityDef, startRot); + } + } + else + { + switch (mode) + { + case WidgetMode.Position: return new EntityPositionUndoStep(EntityDef, startPos); + case WidgetMode.Rotation: return new EntityRotationUndoStep(EntityDef, startRot); + case WidgetMode.Scale: return new EntityScaleUndoStep(EntityDef, startScale); + } + } + } + else if (CarGenerator != null) + { + switch (mode) + { + case WidgetMode.Position: return new CarGenPositionUndoStep(CarGenerator, startPos); + case WidgetMode.Rotation: return new CarGenRotationUndoStep(CarGenerator, startRot); + case WidgetMode.Scale: return new CarGenScaleUndoStep(CarGenerator, startScale); + } + } + else if (CollisionVertex != null) + { + switch (mode) + { + case WidgetMode.Position: return new CollisionVertexPositionUndoStep(CollisionVertex, startPos, wf); + } + } + else if (CollisionPoly != null) + { + switch (mode) + { + case WidgetMode.Position: return new CollisionPolyPositionUndoStep(CollisionPoly, startPos, wf); + case WidgetMode.Rotation: return new CollisionPolyRotationUndoStep(CollisionPoly, startRot, wf); + case WidgetMode.Scale: return new CollisionPolyScaleUndoStep(CollisionPoly, startScale, wf); + } + } + else if (CollisionBounds != null) + { + switch (mode) + { + case WidgetMode.Position: return new CollisionPositionUndoStep(CollisionBounds, startPos, wf); + case WidgetMode.Rotation: return new CollisionRotationUndoStep(CollisionBounds, startRot, wf); + case WidgetMode.Scale: return new CollisionScaleUndoStep(CollisionBounds, startScale, wf); + } + } + else if (PathNode != null) + { + switch (mode) + { + case WidgetMode.Position: return new PathNodePositionUndoStep(PathNode, startPos, wf); + } + } + else if (NavPoly != null) + { + //todo... + } + else if (NavPoint != null) + { + switch (mode) + { + case WidgetMode.Position: return new NavPointPositionUndoStep(NavPoint, startPos, wf); + case WidgetMode.Rotation: return new NavPointRotationUndoStep(NavPoint, startRot, wf); + } + } + else if (NavPortal != null) + { + switch (mode) + { + case WidgetMode.Position: return new NavPortalPositionUndoStep(NavPortal, startPos, wf); + case WidgetMode.Rotation: return new NavPortalRotationUndoStep(NavPortal, startRot, wf); + } + } + else if (TrainTrackNode != null) + { + switch (mode) + { + case WidgetMode.Position: return new TrainTrackNodePositionUndoStep(TrainTrackNode, startPos, wf); + } + } + else if (ScenarioNode != null) + { + switch (mode) + { + case WidgetMode.Position: return new ScenarioNodePositionUndoStep(ScenarioNode, startPos, wf); + case WidgetMode.Rotation: return new ScenarioNodeRotationUndoStep(ScenarioNode, startRot, wf); + } + } + else if (Audio != null) + { + switch (mode) + { + case WidgetMode.Position: return new AudioPositionUndoStep(Audio, startPos); + case WidgetMode.Rotation: return new AudioRotationUndoStep(Audio, startRot); + } + } + return null; + } + + public bool CanShowWidget + { + get + { + bool res = false; + + if (MultipleSelectionItems != null) + { + res = true; + } + else if (EntityDef != null) + { + res = true; + } + else if (CarGenerator != null) + { + res = true; + } + else if (NavPoly != null) + { + res = true; + } + else if (CollisionVertex != null) + { + res = true; + } + else if (CollisionPoly != null) + { + res = true; + } + else if (CollisionBounds != null) + { + res = true; + } + else if (NavPoint != null) + { + res = true; + } + else if (NavPortal != null) + { + res = true; + } + else if (PathNode != null) + { + res = true; + } + else if (TrainTrackNode != null) + { + res = true; + } + else if (ScenarioNode != null) + { + res = true; + } + else if (Audio != null) + { + res = true; + } + return res; + } + } + public Vector3 WidgetPosition + { + get + { + if (MultipleSelectionItems != null) + { + return MultipleSelectionCenter; + } + else if (EntityDef != null) + { + return EntityDef.WidgetPosition; + } + else if (CarGenerator != null) + { + return CarGenerator.Position; + } + else if (CollisionVertex != null) + { + return CollisionVertex.Position; + } + else if (CollisionPoly != null) + { + return CollisionPoly.Position; + } + else if (CollisionBounds != null) + { + return CollisionBounds.Position; + } + else if (NavPoly != null) + { + return NavPoly.Position; + } + else if (NavPoint != null) + { + return NavPoint.Position; + } + else if (NavPortal != null) + { + return NavPortal.Position; + } + else if (PathNode != null) + { + return PathNode.Position; + } + else if (TrainTrackNode != null) + { + return TrainTrackNode.Position; + } + else if (ScenarioNode != null) + { + return ScenarioNode.Position; + } + else if (Audio != null) + { + return Audio.InnerPos; + } + return Vector3.Zero; + } + } + public Quaternion WidgetRotation + { + get + { + if (MultipleSelectionItems != null) + { + return MultipleSelectionRotation; + } + else if (EntityDef != null) + { + return EntityDef.WidgetOrientation; + } + else if (CarGenerator != null) + { + return CarGenerator.Orientation; + } + else if (CollisionVertex != null) + { + return Quaternion.Identity; + } + else if (CollisionPoly != null) + { + return CollisionPoly.Orientation; + } + else if (CollisionBounds != null) + { + return CollisionBounds.Orientation; + } + else if (NavPoly != null) + { + return Quaternion.Identity; + } + else if (NavPoint != null) + { + return NavPoint.Orientation; + } + else if (NavPortal != null) + { + return NavPortal.Orientation; + } + else if (PathNode != null) + { + return Quaternion.Identity; + } + else if (TrainTrackNode != null) + { + return Quaternion.Identity; + } + else if (ScenarioNode != null) + { + return ScenarioNode.Orientation; + } + else if (Audio != null) + { + return Audio.Orientation; + } + return Quaternion.Identity; + } + } + public WidgetAxis WidgetRotationAxes + { + get + { + if (MultipleSelectionItems != null) + { + return WidgetAxis.XYZ; + } + else if (EntityDef != null) + { + return WidgetAxis.XYZ; + } + else if (CarGenerator != null) + { + return WidgetAxis.Z; + } + else if (CollisionVertex != null) + { + return WidgetAxis.None; + } + else if (CollisionPoly != null) + { + return WidgetAxis.XYZ; + } + else if (CollisionBounds != null) + { + return WidgetAxis.XYZ; + } + else if (NavPoly != null) + { + return WidgetAxis.XYZ; + } + else if (NavPoint != null) + { + return WidgetAxis.Z; + } + else if (NavPortal != null) + { + return WidgetAxis.Z; + } + else if (PathNode != null) + { + return WidgetAxis.None; + } + else if (TrainTrackNode != null) + { + return WidgetAxis.None; + } + else if (ScenarioNode != null) + { + return WidgetAxis.Z; + } + else if (Audio != null) + { + return WidgetAxis.Z; + } + return WidgetAxis.None; + } + } + public Vector3 WidgetScale + { + get + { + if (MultipleSelectionItems != null) + { + return MultipleSelectionScale; + } + else if (EntityDef != null) + { + return EntityDef.Scale; + } + else if (CarGenerator != null) + { + return new Vector3(CarGenerator.CCarGen.perpendicularLength); + } + else if (CollisionVertex != null) + { + return Vector3.One; + } + else if (CollisionPoly != null) + { + return CollisionPoly.Scale; + } + else if (CollisionBounds != null) + { + return CollisionBounds.Scale; + } + else if (NavPoly != null) + { + return Vector3.One; + } + else if (NavPoint != null) + { + return Vector3.One; + } + else if (NavPortal != null) + { + return Vector3.One; + } + else if (PathNode != null) + { + return Vector3.One; + } + else if (TrainTrackNode != null) + { + return Vector3.One; + } + else if (ScenarioNode != null) + { + return Vector3.One; + } + else if (Audio != null) + { + return Vector3.One; + } + return Vector3.One; + } + } + public bool WidgetScaleLockXY + { + get + { + if (CollisionBounds != null) + { + return false; + } + if (CollisionPoly != null) + { + return false; + } + return true; + } + } + + + + public void SetPosition(Vector3 newpos, bool editPivot) + { + if (MultipleSelectionItems != null) + { + if (editPivot) + { + } + else + { + var dpos = newpos - MultipleSelectionCenter;// oldpos; + if (dpos == Vector3.Zero) return; //nothing moved.. (probably due to snap) + for (int i = 0; i < MultipleSelectionItems.Length; i++) + { + var refpos = MultipleSelectionItems[i].WidgetPosition; + MultipleSelectionItems[i].SetPosition(refpos + dpos, false); + } + MultipleSelectionCenter = newpos; + } + } + else if (EntityDef != null) + { + if (editPivot) + { + EntityDef.SetPivotPositionFromWidget(newpos); + } + else + { + EntityDef.SetPositionFromWidget(newpos); + } + } + else if (CarGenerator != null) + { + CarGenerator.SetPosition(newpos); + } + else if (PathNode != null) + { + PathNode.SetPosition(newpos); + } + else if (CollisionVertex != null) + { + CollisionVertex.Position = newpos; + } + else if (CollisionPoly != null) + { + CollisionPoly.Position = newpos; + } + else if (CollisionBounds != null) + { + CollisionBounds.Position = newpos; + } + else if (NavPoly != null) + { + NavPoly.SetPosition(newpos); + } + else if (NavPoint != null) + { + NavPoint.SetPosition(newpos); + } + else if (NavPortal != null) + { + NavPortal.SetPosition(newpos); + } + else if (TrainTrackNode != null) + { + TrainTrackNode.SetPosition(newpos); + } + else if (ScenarioNode != null) + { + ScenarioNode.SetPosition(newpos); + } + else if (Audio != null) + { + Audio.SetPosition(newpos); + } + + } + public void SetRotation(Quaternion newrot, bool editPivot) + { + if (MultipleSelectionItems != null) + { + if (editPivot) + { + } + else + { + var cen = MultipleSelectionCenter; + var orinv = Quaternion.Invert(MultipleSelectionRotation); + var trans = newrot * orinv; + for (int i = 0; i < MultipleSelectionItems.Length; i++) + { + var refpos = MultipleSelectionItems[i].WidgetPosition; + var relpos = refpos - cen; + var newpos = trans.Multiply(relpos) + cen; + var refori = MultipleSelectionItems[i].WidgetRotation; + var newori = trans * refori; + MultipleSelectionItems[i].SetPosition(newpos, false); + MultipleSelectionItems[i].SetRotation(newori, false); + } + MultipleSelectionRotation = newrot; + } + } + else if (EntityDef != null) + { + if (editPivot) + { + EntityDef.SetPivotOrientationFromWidget(newrot); + } + else + { + EntityDef.SetOrientationFromWidget(newrot); + } + } + else if (CarGenerator != null) + { + CarGenerator.SetOrientation(newrot); + } + else if (CollisionVertex != null) + { + //do nothing, but stop any poly from being rotated also + } + else if (CollisionPoly != null) + { + CollisionPoly.Orientation = newrot; + } + else if (CollisionBounds != null) + { + CollisionBounds.Orientation = newrot; + } + else if (ScenarioNode != null) + { + ScenarioNode.SetOrientation(newrot); + } + else if (NavPoint != null) + { + NavPoint.SetOrientation(newrot); + } + else if (NavPortal != null) + { + NavPortal.SetOrientation(newrot); + } + else if (Audio != null) + { + Audio.SetOrientation(newrot); + } + } + public void SetScale(Vector3 newscale, bool editPivot) + { + if (MultipleSelectionItems != null) + { + if (editPivot) + {//editing pivot scale is sort of meaningless.. + } + else + { + var cen = MultipleSelectionCenter; + var ori = MultipleSelectionRotation; + var orinv = Quaternion.Invert(ori); + var rsca = newscale / MultipleSelectionScale; + for (int i = 0; i < MultipleSelectionItems.Length; i++) + { + var refpos = MultipleSelectionItems[i].WidgetPosition; + var relpos = refpos - cen; + var newpos = ori.Multiply(orinv.Multiply(relpos) * rsca) + cen; + MultipleSelectionItems[i].SetPosition(newpos, false); + MultipleSelectionItems[i].SetScale(newscale, false); + } + MultipleSelectionScale = newscale; + } + } + else if (EntityDef != null) + { + EntityDef.SetScale(newscale); + } + else if (CarGenerator != null) + { + CarGenerator.SetScale(newscale); + AABB = new BoundingBox(CarGenerator.BBMin, CarGenerator.BBMax); + } + else if (CollisionPoly != null) + { + CollisionPoly.Scale = newscale; + } + else if (CollisionBounds != null) + { + CollisionBounds.Scale = newscale; + } + } + + + public override string ToString() + { + return GetFullNameString("[Empty]"); + } + } + + + +} diff --git a/World/WorldInfoForm.cs b/World/WorldInfoForm.cs index 4ddc3cd..fc74d4a 100644 --- a/World/WorldInfoForm.cs +++ b/World/WorldInfoForm.cs @@ -22,7 +22,6 @@ namespace CodeWalker { WorldForm WorldForm; MapSelection Selection; - List SelectionItems; string SelectionMode = ""; bool MouseSelectEnable = false; @@ -60,10 +59,9 @@ namespace CodeWalker MouseSelectCheckBox.Checked = enable; } - public void SetSelection(MapSelection item, List multiItems) + public void SetSelection(MapSelection item) { Selection = item; - SelectionItems = multiItems; SelectionNameTextBox.Text = item.GetNameString("Nothing selected"); //SelEntityPropertyGrid.SelectedObject = item.EntityDef; @@ -89,10 +87,10 @@ namespace CodeWalker AddSelectionEntityHierarchyNodes(item.EntityDef); } - if (item.MultipleSelection) + if (item.MultipleSelectionItems != null) { SelectionEntityTabPage.Text = "Multiple items"; - SelEntityPropertyGrid.SelectedObject = multiItems.ToArray(); + SelEntityPropertyGrid.SelectedObject = item.MultipleSelectionItems; } else if (item.TimeCycleModifier != null) { @@ -450,7 +448,7 @@ namespace CodeWalker private void WorldInfoForm_Load(object sender, EventArgs e) { - SetSelection(Selection, SelectionItems); + SetSelection(Selection); } private void WorldInfoForm_FormClosed(object sender, FormClosedEventArgs e) diff --git a/WorldForm.Designer.cs b/WorldForm.Designer.cs index 24a894d..1306c02 100644 --- a/WorldForm.Designer.cs +++ b/WorldForm.Designer.cs @@ -296,6 +296,10 @@ namespace CodeWalker this.ToolbarPanel = new System.Windows.Forms.Panel(); this.SubtitleLabel = new System.Windows.Forms.Label(); this.SubtitleTimer = new System.Windows.Forms.Timer(this.components); + this.ToolbarNewYbnButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarOpenYbnButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarNewYtypButton = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolbarOpenYtypButton = new System.Windows.Forms.ToolStripMenuItem(); this.StatusStrip.SuspendLayout(); this.ToolsPanel.SuspendLayout(); this.ToolsTabControl.SuspendLayout(); @@ -2836,7 +2840,7 @@ namespace CodeWalker this.ToolbarCameraModeButton}); this.Toolbar.Location = new System.Drawing.Point(1, 0); this.Toolbar.Name = "Toolbar"; - this.Toolbar.Size = new System.Drawing.Size(554, 25); + this.Toolbar.Size = new System.Drawing.Size(585, 25); this.Toolbar.TabIndex = 6; this.Toolbar.Text = "toolStrip1"; // @@ -2846,6 +2850,8 @@ namespace CodeWalker this.ToolbarNewButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ToolbarNewProjectButton, this.ToolbarNewYmapButton, + this.ToolbarNewYtypButton, + this.ToolbarNewYbnButton, this.ToolbarNewYndButton, this.ToolbarNewTrainsButton, this.ToolbarNewScenarioButton}); @@ -2861,35 +2867,35 @@ namespace CodeWalker // ToolbarNewProjectButton // this.ToolbarNewProjectButton.Name = "ToolbarNewProjectButton"; - this.ToolbarNewProjectButton.Size = new System.Drawing.Size(164, 22); + this.ToolbarNewProjectButton.Size = new System.Drawing.Size(180, 22); this.ToolbarNewProjectButton.Text = "New project"; this.ToolbarNewProjectButton.Click += new System.EventHandler(this.ToolbarNewProjectButton_Click); // // ToolbarNewYmapButton // this.ToolbarNewYmapButton.Name = "ToolbarNewYmapButton"; - this.ToolbarNewYmapButton.Size = new System.Drawing.Size(164, 22); + this.ToolbarNewYmapButton.Size = new System.Drawing.Size(180, 22); this.ToolbarNewYmapButton.Text = "New ymap file"; this.ToolbarNewYmapButton.Click += new System.EventHandler(this.ToolbarNewYmapButton_Click); // // ToolbarNewYndButton // this.ToolbarNewYndButton.Name = "ToolbarNewYndButton"; - this.ToolbarNewYndButton.Size = new System.Drawing.Size(164, 22); + this.ToolbarNewYndButton.Size = new System.Drawing.Size(180, 22); this.ToolbarNewYndButton.Text = "New ynd file"; this.ToolbarNewYndButton.Click += new System.EventHandler(this.ToolbarNewYndButton_Click); // // ToolbarNewTrainsButton // this.ToolbarNewTrainsButton.Name = "ToolbarNewTrainsButton"; - this.ToolbarNewTrainsButton.Size = new System.Drawing.Size(164, 22); + this.ToolbarNewTrainsButton.Size = new System.Drawing.Size(180, 22); this.ToolbarNewTrainsButton.Text = "New trains file"; this.ToolbarNewTrainsButton.Click += new System.EventHandler(this.ToolbarNewTrainsButton_Click); // // ToolbarNewScenarioButton // this.ToolbarNewScenarioButton.Name = "ToolbarNewScenarioButton"; - this.ToolbarNewScenarioButton.Size = new System.Drawing.Size(164, 22); + this.ToolbarNewScenarioButton.Size = new System.Drawing.Size(180, 22); this.ToolbarNewScenarioButton.Text = "New scenario file"; this.ToolbarNewScenarioButton.Click += new System.EventHandler(this.ToolbarNewScenarioButton_Click); // @@ -2899,6 +2905,8 @@ namespace CodeWalker this.ToolbarOpenButton.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.ToolbarOpenProjectButton, this.ToolbarOpenYmapButton, + this.ToolbarOpenYtypButton, + this.ToolbarOpenYbnButton, this.ToolbarOpenYndButton, this.ToolbarOpenTrainsButton, this.ToolbarOpenScenarioButton}); @@ -2914,35 +2922,35 @@ namespace CodeWalker // ToolbarOpenProjectButton // this.ToolbarOpenProjectButton.Name = "ToolbarOpenProjectButton"; - this.ToolbarOpenProjectButton.Size = new System.Drawing.Size(178, 22); + this.ToolbarOpenProjectButton.Size = new System.Drawing.Size(180, 22); this.ToolbarOpenProjectButton.Text = "Open project..."; this.ToolbarOpenProjectButton.Click += new System.EventHandler(this.ToolbarOpenProjectButton_Click); // // ToolbarOpenYmapButton // this.ToolbarOpenYmapButton.Name = "ToolbarOpenYmapButton"; - this.ToolbarOpenYmapButton.Size = new System.Drawing.Size(178, 22); + this.ToolbarOpenYmapButton.Size = new System.Drawing.Size(180, 22); this.ToolbarOpenYmapButton.Text = "Open ymap file..."; this.ToolbarOpenYmapButton.Click += new System.EventHandler(this.ToolbarOpenYmapButton_Click); // // ToolbarOpenYndButton // this.ToolbarOpenYndButton.Name = "ToolbarOpenYndButton"; - this.ToolbarOpenYndButton.Size = new System.Drawing.Size(178, 22); + this.ToolbarOpenYndButton.Size = new System.Drawing.Size(180, 22); this.ToolbarOpenYndButton.Text = "Open ynd file..."; this.ToolbarOpenYndButton.Click += new System.EventHandler(this.ToolbarOpenYndButton_Click); // // ToolbarOpenTrainsButton // this.ToolbarOpenTrainsButton.Name = "ToolbarOpenTrainsButton"; - this.ToolbarOpenTrainsButton.Size = new System.Drawing.Size(178, 22); + this.ToolbarOpenTrainsButton.Size = new System.Drawing.Size(180, 22); this.ToolbarOpenTrainsButton.Text = "Open trains file..."; this.ToolbarOpenTrainsButton.Click += new System.EventHandler(this.ToolbarOpenTrainsButton_Click); // // ToolbarOpenScenarioButton // this.ToolbarOpenScenarioButton.Name = "ToolbarOpenScenarioButton"; - this.ToolbarOpenScenarioButton.Size = new System.Drawing.Size(178, 22); + this.ToolbarOpenScenarioButton.Size = new System.Drawing.Size(180, 22); this.ToolbarOpenScenarioButton.Text = "Open scenario file..."; this.ToolbarOpenScenarioButton.Click += new System.EventHandler(this.ToolbarOpenScenarioButton_Click); // @@ -3428,6 +3436,34 @@ namespace CodeWalker // this.SubtitleTimer.Tick += new System.EventHandler(this.SubtitleTimer_Tick); // + // ToolbarNewYbnButton + // + this.ToolbarNewYbnButton.Name = "ToolbarNewYbnButton"; + this.ToolbarNewYbnButton.Size = new System.Drawing.Size(180, 22); + this.ToolbarNewYbnButton.Text = "New ybn file"; + this.ToolbarNewYbnButton.Click += new System.EventHandler(this.ToolbarNewYbnButton_Click); + // + // ToolbarOpenYbnButton + // + this.ToolbarOpenYbnButton.Name = "ToolbarOpenYbnButton"; + this.ToolbarOpenYbnButton.Size = new System.Drawing.Size(180, 22); + this.ToolbarOpenYbnButton.Text = "Open ybn file..."; + this.ToolbarOpenYbnButton.Click += new System.EventHandler(this.ToolbarOpenYbnButton_Click); + // + // ToolbarNewYtypButton + // + this.ToolbarNewYtypButton.Name = "ToolbarNewYtypButton"; + this.ToolbarNewYtypButton.Size = new System.Drawing.Size(180, 22); + this.ToolbarNewYtypButton.Text = "New ytyp file"; + this.ToolbarNewYtypButton.Click += new System.EventHandler(this.ToolbarNewYtypButton_Click); + // + // ToolbarOpenYtypButton + // + this.ToolbarOpenYtypButton.Name = "ToolbarOpenYtypButton"; + this.ToolbarOpenYtypButton.Size = new System.Drawing.Size(180, 22); + this.ToolbarOpenYtypButton.Text = "Open ytyp file..."; + this.ToolbarOpenYtypButton.Click += new System.EventHandler(this.ToolbarOpenYtypButton_Click); + // // WorldForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -3783,5 +3819,9 @@ namespace CodeWalker private System.Windows.Forms.Label SubtitleLabel; private System.Windows.Forms.Timer SubtitleTimer; private System.Windows.Forms.CheckBox DeferredShadingCheckBox; + private System.Windows.Forms.ToolStripMenuItem ToolbarNewYbnButton; + private System.Windows.Forms.ToolStripMenuItem ToolbarOpenYbnButton; + private System.Windows.Forms.ToolStripMenuItem ToolbarNewYtypButton; + private System.Windows.Forms.ToolStripMenuItem ToolbarOpenYtypButton; } } \ No newline at end of file diff --git a/WorldForm.cs b/WorldForm.cs index 7b6eee9..c85e8dc 100644 --- a/WorldForm.cs +++ b/WorldForm.cs @@ -161,7 +161,7 @@ namespace CodeWalker string SelectionModeStr = "Entity"; MapSelectionMode SelectionMode = MapSelectionMode.Entity; MapSelection SelectedItem; - List SelectedItems = new List(); + MapSelection CopiedItem; WorldInfoForm InfoForm = null; @@ -182,15 +182,6 @@ namespace CodeWalker WorldSnapMode SnapModePrev = WorldSnapMode.Ground;//also the default snap mode float SnapGridSize = 1.0f; - YmapEntityDef CopiedEntity = null; - YmapCarGen CopiedCarGen = null; - YndNode CopiedPathNode = null; - YnvPoly CopiedNavPoly = null; - YnvPoint CopiedNavPoint = null; - YnvPortal CopiedNavPortal = null; - TrainTrackNode CopiedTrainNode = null; - ScenarioNode CopiedScenarioNode = null; - AudioPlacement CopiedAudio = null; public bool EditEntityPivot { get; set; } = false; @@ -1111,65 +1102,11 @@ namespace CodeWalker PrevMouseHit = LastMouseHit; LastMouseHit = CurMouseHit; - bool change = (LastMouseHit.EntityDef != PrevMouseHit.EntityDef); + bool change = LastMouseHit.CheckForChanges(PrevMouseHit); //(LastMouseHit.EntityDef != PrevMouseHit.EntityDef); if (SelectByGeometry) { change = change || (LastMouseHit.Geometry != PrevMouseHit.Geometry); } - switch (SelectionMode) - { - case MapSelectionMode.EntityExtension: - change = change || (LastMouseHit.EntityExtension != PrevMouseHit.EntityExtension); - break; - case MapSelectionMode.ArchetypeExtension: - change = change || (LastMouseHit.ArchetypeExtension != PrevMouseHit.ArchetypeExtension); - break; - case MapSelectionMode.TimeCycleModifier: - change = change || (LastMouseHit.TimeCycleModifier != PrevMouseHit.TimeCycleModifier); - break; - case MapSelectionMode.CarGenerator: - change = change || (LastMouseHit.CarGenerator != PrevMouseHit.CarGenerator); - break; - case MapSelectionMode.MloInstance: - change = change || (LastMouseHit.MloEntityDef != PrevMouseHit.MloEntityDef); - break; - case MapSelectionMode.DistantLodLights: - change = change || (LastMouseHit.DistantLodLights != PrevMouseHit.DistantLodLights); - break; - case MapSelectionMode.Grass: - change = change || (LastMouseHit.GrassBatch != PrevMouseHit.GrassBatch); - break; - case MapSelectionMode.Occlusion: - change = change || (LastMouseHit.BoxOccluder != PrevMouseHit.BoxOccluder) - || (LastMouseHit.OccludeModel != PrevMouseHit.OccludeModel); - break; - case MapSelectionMode.WaterQuad: - change = change || (LastMouseHit.WaterQuad != PrevMouseHit.WaterQuad); - break; - case MapSelectionMode.Collision: - change = change || (LastMouseHit.CollisionBounds != PrevMouseHit.CollisionBounds) - || (LastMouseHit.CollisionPoly != PrevMouseHit.CollisionPoly) - || (LastMouseHit.CollisionVertex != PrevMouseHit.CollisionVertex); - break; - case MapSelectionMode.NavMesh: - change = change || (LastMouseHit.NavPoly != PrevMouseHit.NavPoly) - || (LastMouseHit.NavPoint != PrevMouseHit.NavPoint) - || (LastMouseHit.NavPortal != PrevMouseHit.NavPortal); - break; - case MapSelectionMode.Path: - change = change || (LastMouseHit.PathNode != PrevMouseHit.PathNode); - break; - case MapSelectionMode.TrainTrack: - change = change || (LastMouseHit.TrainTrackNode != PrevMouseHit.TrainTrackNode); - break; - case MapSelectionMode.Scenario: - change = change || (LastMouseHit.ScenarioNode != PrevMouseHit.ScenarioNode); - break; - case MapSelectionMode.Audio: - change = change || (LastMouseHit.Audio != PrevMouseHit.Audio); - break; - } - if (change) { @@ -1275,11 +1212,11 @@ namespace CodeWalker private void RenderSelection() { - if (SelectedItem.MultipleSelection) + if (SelectedItem.MultipleSelectionItems != null) { - for (int i = 0; i < SelectedItems.Count; i++) + for (int i = 0; i < SelectedItem.MultipleSelectionItems.Length; i++) { - var item = SelectedItems[i]; + var item = SelectedItem.MultipleSelectionItems[i]; RenderSelection(ref item); } } @@ -1697,30 +1634,11 @@ namespace CodeWalker if (newpos == oldpos) return; - if (SelectedItem.MultipleSelection) - { - if (EditEntityPivot) - { - } - else - { - var dpos = newpos - SelectedItem.MultipleSelectionCenter;// oldpos; - if (dpos == Vector3.Zero) return; //nothing moved.. (probably due to snap) - for (int i = 0; i < SelectedItems.Count; i++) - { - var refpos = SelectedItems[i].WidgetPosition; - SelectedItems[i].SetPosition(refpos + dpos, false); - } - SelectedItem.MultipleSelectionCenter = newpos; - } - } - else - { - SelectedItem.SetPosition(newpos, EditEntityPivot); - } + SelectedItem.SetPosition(newpos, EditEntityPivot); + if (ProjectForm != null) { - ProjectForm.OnWorldSelectionModified(SelectedItem, SelectedItems); + ProjectForm.OnWorldSelectionModified(SelectedItem); } } private void Widget_OnRotationChange(Quaternion newrot, Quaternion oldrot) @@ -1728,22 +1646,11 @@ namespace CodeWalker //called during UpdateWidgets() if (newrot == oldrot) return; - if (SelectedItem.MultipleSelection) - { - if (EditEntityPivot) - { - } - else - { - } - } - else - { - SelectedItem.SetRotation(newrot, oldrot, EditEntityPivot); - } + SelectedItem.SetRotation(newrot, EditEntityPivot); + if (ProjectForm != null) { - ProjectForm.OnWorldSelectionModified(SelectedItem, SelectedItems); + ProjectForm.OnWorldSelectionModified(SelectedItem); } } private void Widget_OnScaleChange(Vector3 newscale, Vector3 oldscale) @@ -1751,22 +1658,11 @@ namespace CodeWalker //called during UpdateWidgets() if (newscale == oldscale) return; - if (SelectedItem.MultipleSelection) - { - if (EditEntityPivot) - {//editing pivot scale is sort of meaningless.. - } - else - { - } - } - else - { - SelectedItem.SetScale(newscale, oldscale, EditEntityPivot); - } + SelectedItem.SetScale(newscale, EditEntityPivot); + if (ProjectForm != null) { - ProjectForm.OnWorldSelectionModified(SelectedItem, SelectedItems); + ProjectForm.OnWorldSelectionModified(SelectedItem); } } @@ -3351,38 +3247,42 @@ namespace CodeWalker if (addSelection) { - if (SelectedItem.MultipleSelection) + var items = new List(); + if (SelectedItem.MultipleSelectionItems != null) { + items.AddRange(SelectedItem.MultipleSelectionItems); + if (mhitv.HasValue) //incoming selection isn't empty... { //search the list for a match, remove it if already there, otherwise add it. bool found = false; - foreach (var item in SelectedItems) + foreach (var item in items) { if (!item.CheckForChanges(mhitv)) { - SelectedItems.Remove(item); + items.Remove(item); found = true; break; } } if (found) { - if (SelectedItems.Count == 1) + if (items.Count == 1) { - mhitv = SelectedItems[0]; - SelectedItems.Clear(); + mhitv = items[0]; + items.Clear(); } - else if (SelectedItems.Count <= 0) + else if (items.Count <= 0) { mhitv.Clear(); - SelectedItems.Clear();//this shouldn't really happen.. + items.Clear();//this shouldn't really happen.. } + mhitv.MultipleSelectionItems = items.ToArray(); } else { - mhitv.MultipleSelection = false; - SelectedItems.Add(mhitv); + mhitv.MultipleSelectionItems = null; + items.Add(mhitv); } change = true; } @@ -3399,11 +3299,11 @@ namespace CodeWalker { if (SelectedItem.HasValue) //add the existing item to the selection list, if it's not empty { - SelectedItem.MultipleSelection = false; - SelectedItems.Add(SelectedItem); - mhitv.MultipleSelection = false; - SelectedItems.Add(mhitv); - SelectedItem.MultipleSelection = true; + mhitv.MultipleSelectionItems = null; + SelectedItem.MultipleSelectionItems = null; + items.Add(SelectedItem); + items.Add(mhitv); + SelectedItem.MultipleSelectionItems = items.ToArray(); } } else //empty incoming value... do nothing? @@ -3414,39 +3314,39 @@ namespace CodeWalker else //same thing was selected a 2nd time, just clear the selection. { SelectedItem.Clear(); - SelectedItems.Clear(); mhit = null; //dont's wants to selects it agains! change = true; } } - if (SelectedItems.Count > 1) + if (items.Count > 1) { //iterate the selected items, and calculate the selection position var center = Vector3.Zero; - foreach (var item in SelectedItems) + foreach (var item in items) { center += item.WidgetPosition; } - if (SelectedItems.Count > 0) + if (items.Count > 0) { - center *= (1.0f / SelectedItems.Count); + center *= (1.0f / items.Count); } mhitv.Clear(); - mhitv.MultipleSelection = true; + mhitv.MultipleSelectionItems = items.ToArray(); mhitv.MultipleSelectionCenter = center; + mhitv.MultipleSelectionRotation = Quaternion.Identity; + mhitv.MultipleSelectionScale = Vector3.One; } } else { - if (SelectedItem.MultipleSelection) + if (SelectedItem.MultipleSelectionItems != null) { change = true; - SelectedItem.MultipleSelection = false; + SelectedItem.MultipleSelectionItems = null; SelectedItem.Clear(); } - SelectedItems.Clear(); } if (!change) @@ -3801,7 +3701,7 @@ namespace CodeWalker if (InfoForm != null) { - InfoForm.SetSelection(SelectedItem, SelectedItems); + InfoForm.SetSelection(SelectedItem); } } } @@ -3838,10 +3738,10 @@ namespace CodeWalker ToolbarDeleteItemButton.Enabled = false; ToolbarDeleteItemButton.Text = "Delete"; - if (item.MultipleSelection) + if (item.MultipleSelectionItems != null) { SelectionEntityTabPage.Text = "Multiple items"; - SelEntityPropertyGrid.SelectedObject = SelectedItems.ToArray(); + SelEntityPropertyGrid.SelectedObject = item.MultipleSelectionItems; } else if (item.TimeCycleModifier != null) { @@ -4148,7 +4048,7 @@ namespace CodeWalker if (InfoForm == null) { InfoForm = new WorldInfoForm(this); - InfoForm.SetSelection(SelectedItem, SelectedItems); + InfoForm.SetSelection(SelectedItem); InfoForm.SetSelectionMode(SelectionModeStr, MouseSelectEnabled); InfoForm.Show(this); } @@ -4847,25 +4747,9 @@ namespace CodeWalker - private bool CanMarkUndo() - { - if (SelectedItem.MultipleSelection) return true; - if (SelectedItem.EntityDef != null) return true; - if (SelectedItem.CarGenerator != null) return true; - if (SelectedItem.CollisionBounds != null) return true; - if (SelectedItem.CollisionPoly != null) return true; - if (SelectedItem.PathNode != null) return true; - //if (SelectedItem.NavPoly != null) return true; - if (SelectedItem.NavPoint != null) return true; - if (SelectedItem.NavPortal != null) return true; - if (SelectedItem.TrainTrackNode != null) return true; - if (SelectedItem.ScenarioNode != null) return true; - if (SelectedItem.Audio != null) return true; - return false; - } private void MarkUndoStart(Widget w) { - if (!CanMarkUndo()) return; + if (!SelectedItem.CanMarkUndo()) return; if (Widget is TransformWidget) { UndoStartPosition = Widget.Position; @@ -4875,134 +4759,12 @@ namespace CodeWalker } private void MarkUndoEnd(Widget w) { - if (!CanMarkUndo()) return; - var ent = SelectedItem.EntityDef; - var cargen = SelectedItem.CarGenerator; - var bounds = SelectedItem.CollisionBounds; - var boundpoly = SelectedItem.CollisionPoly; - var boundvertex = SelectedItem.CollisionVertex; - var pathnode = SelectedItem.PathNode; - var navpoly = SelectedItem.NavPoly; - var navpoint = SelectedItem.NavPoint; - var navportal = SelectedItem.NavPortal; - var trainnode = SelectedItem.TrainTrackNode; - var scenarionode = SelectedItem.ScenarioNode; - var audio = SelectedItem.Audio; + if (!SelectedItem.CanMarkUndo()) return; TransformWidget tw = Widget as TransformWidget; UndoStep s = null; if (tw != null) { - if (SelectedItem.MultipleSelection) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new MultiPositionUndoStep(SelectedItem, SelectedItems.ToArray(), UndoStartPosition, this); break; - } - } - else if (ent != null) - { - if (EditEntityPivot) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new EntityPivotPositionUndoStep(ent, UndoStartPosition); break; - case WidgetMode.Rotation: s = new EntityPivotRotationUndoStep(ent, UndoStartRotation); break; - } - } - else - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new EntityPositionUndoStep(ent, UndoStartPosition); break; - case WidgetMode.Rotation: s = new EntityRotationUndoStep(ent, UndoStartRotation); break; - case WidgetMode.Scale: s = new EntityScaleUndoStep(ent, UndoStartScale); break; - } - } - } - else if (cargen != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new CarGenPositionUndoStep(cargen, UndoStartPosition); break; - case WidgetMode.Rotation: s = new CarGenRotationUndoStep(cargen, UndoStartRotation); break; - case WidgetMode.Scale: s = new CarGenScaleUndoStep(cargen, UndoStartScale); break; - } - } - else if (boundvertex != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new CollisionVertexPositionUndoStep(boundvertex, UndoStartPosition, this); break; - } - } - else if (boundpoly != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new CollisionPolyPositionUndoStep(boundpoly, UndoStartPosition, this); break; - case WidgetMode.Rotation: s = new CollisionPolyRotationUndoStep(boundpoly, UndoStartRotation, this); break; - case WidgetMode.Scale: s = new CollisionPolyScaleUndoStep(boundpoly, UndoStartScale, this); break; - } - } - else if (bounds != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new CollisionPositionUndoStep(bounds, UndoStartPosition, this); break; - case WidgetMode.Rotation: s = new CollisionRotationUndoStep(bounds, UndoStartRotation, this); break; - case WidgetMode.Scale: s = new CollisionScaleUndoStep(bounds, UndoStartScale, this); break; - } - } - else if (pathnode != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new PathNodePositionUndoStep(pathnode, UndoStartPosition, this); break; - } - } - else if (navpoly != null) - { - //todo... - } - else if (navpoint != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new NavPointPositionUndoStep(navpoint, UndoStartPosition, this); break; - case WidgetMode.Rotation: s = new NavPointRotationUndoStep(navpoint, UndoStartRotation, this); break; - } - } - else if (navportal != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new NavPortalPositionUndoStep(navportal, UndoStartPosition, this); break; - case WidgetMode.Rotation: s = new NavPortalRotationUndoStep(navportal, UndoStartRotation, this); break; - } - } - else if (trainnode != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new TrainTrackNodePositionUndoStep(trainnode, UndoStartPosition, this); break; - } - } - else if (scenarionode != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new ScenarioNodePositionUndoStep(scenarionode, UndoStartPosition, this); break; - case WidgetMode.Rotation: s = new ScenarioNodeRotationUndoStep(scenarionode, UndoStartRotation, this); break; - } - } - else if (audio != null) - { - switch (tw.Mode) - { - case WidgetMode.Position: s = new AudioPositionUndoStep(audio, UndoStartPosition); break; - case WidgetMode.Rotation: s = new AudioRotationUndoStep(audio, UndoStartRotation); break; - } - } + s = SelectedItem.CreateUndoStep(tw.Mode, UndoStartPosition, UndoStartRotation, UndoStartScale, this, EditEntityPivot); } if (s != null) { @@ -5021,7 +4783,7 @@ namespace CodeWalker if (ProjectForm != null) { - ProjectForm.OnWorldSelectionModified(SelectedItem, SelectedItems); + ProjectForm.OnWorldSelectionModified(SelectedItem); } UpdateUndoUI(); @@ -5036,7 +4798,7 @@ namespace CodeWalker if (ProjectForm != null) { - ProjectForm.OnWorldSelectionModified(SelectedItem, SelectedItems); + ProjectForm.OnWorldSelectionModified(SelectedItem); } UpdateUndoUI(); @@ -5127,7 +4889,7 @@ namespace CodeWalker ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : ""); ToolbarAddItemButton.Enabled = enable; //ToolbarDeleteEntityButton.Enabled = enable; - ToolbarPasteButton.Enabled = (CopiedEntity != null) && enable; + ToolbarPasteButton.Enabled = (CopiedItem.EntityDef != null) && enable; } public void EnableYbnUI(bool enable, string filename) { @@ -5137,7 +4899,7 @@ namespace CodeWalker //ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : ""); //ToolbarAddItemButton.Enabled = enable; ////ToolbarDeleteEntityButton.Enabled = enable; - //ToolbarPasteButton.Enabled = (CopiedCollisionPoly != null) && enable; + //ToolbarPasteButton.Enabled = (CopiedItem.CollisionPoly != null) && enable; } } public void EnableYndUI(bool enable, string filename) @@ -5153,7 +4915,7 @@ namespace CodeWalker ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : ""); ToolbarAddItemButton.Enabled = enable; //ToolbarDeleteEntityButton.Enabled = enable; - ToolbarPasteButton.Enabled = (CopiedPathNode != null) && enable; + ToolbarPasteButton.Enabled = (CopiedItem.PathNode != null) && enable; } } public void EnableYnvUI(bool enable, string filename) @@ -5169,7 +4931,7 @@ namespace CodeWalker ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : ""); ToolbarAddItemButton.Enabled = enable; //ToolbarDeleteEntityButton.Enabled = enable; - ToolbarPasteButton.Enabled = (CopiedNavPoly != null) && enable; + ToolbarPasteButton.Enabled = (CopiedItem.NavPoly != null) && enable; } } public void EnableTrainsUI(bool enable, string filename) @@ -5185,7 +4947,7 @@ namespace CodeWalker ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : ""); ToolbarAddItemButton.Enabled = enable; //ToolbarDeleteEntityButton.Enabled = enable; - ToolbarPasteButton.Enabled = false;// (CopiedTrainNode != null) && enable; + ToolbarPasteButton.Enabled = false;// (CopiedItem.TrainNode != null) && enable; } } public void EnableScenarioUI(bool enable, string filename) @@ -5201,7 +4963,7 @@ namespace CodeWalker ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : ""); ToolbarAddItemButton.Enabled = enable; //ToolbarDeleteEntityButton.Enabled = enable; - ToolbarPasteButton.Enabled = (CopiedScenarioNode != null) && enable; + ToolbarPasteButton.Enabled = (CopiedItem.ScenarioNode != null) && enable; } } public void EnableAudioUI(bool enable, string filename) //TODO @@ -5233,6 +4995,16 @@ namespace CodeWalker ShowProjectForm(); ProjectForm.NewYmap(); } + private void NewYtyp() + { + ShowProjectForm(); + ProjectForm.NewYtyp(); + } + private void NewYbn() + { + ShowProjectForm(); + ProjectForm.NewYbn(); + } private void NewYnd() { ShowProjectForm(); @@ -5281,6 +5053,16 @@ namespace CodeWalker ShowProjectForm(); ProjectForm.OpenYmap(); } + private void OpenYtyp() + { + ShowProjectForm(); + ProjectForm.OpenYtyp(); + } + private void OpenYbn() + { + ShowProjectForm(); + ProjectForm.OpenYbn(); + } private void OpenYnd() { ShowProjectForm(); @@ -5346,6 +5128,7 @@ namespace CodeWalker } private void CopyItem() { + CopiedItem = SelectedItem; if (SelectedItem.EntityDef != null) CopyEntity(); else if (SelectedItem.CarGenerator != null) CopyCarGen(); else if (SelectedItem.PathNode != null) CopyPathNode(); @@ -5359,16 +5142,16 @@ namespace CodeWalker } private void PasteItem() { - if (CopiedEntity != null) PasteEntity(); - else if (CopiedCarGen != null) PasteCarGen(); - else if (CopiedPathNode != null) PastePathNode(); - else if (CopiedNavPoly != null) PasteNavPoly(); - else if (CopiedNavPoint != null) PasteNavPoint(); - else if (CopiedNavPortal != null) PasteNavPortal(); - else if (CopiedTrainNode != null) PasteTrainNode(); - else if (CopiedScenarioNode != null) PasteScenarioNode(); - else if (CopiedAudio?.AudioZone != null) PasteAudioZone(); - else if (CopiedAudio?.AudioEmitter != null) PasteAudioEmitter(); + if (CopiedItem.EntityDef != null) PasteEntity(); + else if (CopiedItem.CarGenerator != null) PasteCarGen(); + else if (CopiedItem.PathNode != null) PastePathNode(); + else if (CopiedItem.NavPoly != null) PasteNavPoly(); + else if (CopiedItem.NavPoint != null) PasteNavPoint(); + else if (CopiedItem.NavPortal != null) PasteNavPortal(); + else if (CopiedItem.TrainTrackNode != null) PasteTrainNode(); + else if (CopiedItem.ScenarioNode != null) PasteScenarioNode(); + else if (CopiedItem.Audio?.AudioZone != null) PasteAudioZone(); + else if (CopiedItem.Audio?.AudioEmitter != null) PasteAudioEmitter(); } private void CloneItem() { @@ -5439,22 +5222,21 @@ namespace CodeWalker } private void CopyEntity() { - CopiedEntity = SelectedItem.EntityDef; - ToolbarPasteButton.Enabled = (CopiedEntity != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.EntityDef != null) && ToolbarAddItemButton.Enabled; } private void PasteEntity() { - if (CopiedEntity == null) return; + if (CopiedItem.EntityDef == null) return; if (ProjectForm == null) return; - MloInstanceData instance = CopiedEntity.MloParent?.MloInstance; - MCEntityDef entdef = instance?.TryGetArchetypeEntity(CopiedEntity); + MloInstanceData instance = CopiedItem.EntityDef.MloParent?.MloInstance; + MCEntityDef entdef = instance?.TryGetArchetypeEntity(CopiedItem.EntityDef); if (entdef != null) { - ProjectForm.NewMloEntity(CopiedEntity, true); + ProjectForm.NewMloEntity(CopiedItem.EntityDef, true); } else { - ProjectForm.NewEntity(CopiedEntity, true); + ProjectForm.NewEntity(CopiedItem.EntityDef, true); } } private void CloneEntity() @@ -5501,14 +5283,13 @@ namespace CodeWalker } private void CopyCarGen() { - CopiedCarGen = SelectedItem.CarGenerator; - ToolbarPasteButton.Enabled = (CopiedCarGen != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.CarGenerator != null) && ToolbarAddItemButton.Enabled; } private void PasteCarGen() { - if (CopiedCarGen == null) return; + if (CopiedItem.CarGenerator == null) return; if (ProjectForm == null) return; - ProjectForm.NewCarGen(CopiedCarGen); + ProjectForm.NewCarGen(CopiedItem.CarGenerator); } private void CloneCarGen() { @@ -5555,14 +5336,13 @@ namespace CodeWalker } private void CopyPathNode() { - CopiedPathNode = SelectedItem.PathNode; - ToolbarPasteButton.Enabled = (CopiedPathNode != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.PathNode != null) && ToolbarAddItemButton.Enabled; } private void PastePathNode() { - if (CopiedPathNode == null) return; + if (CopiedItem.PathNode == null) return; if (ProjectForm == null) return; - ProjectForm.NewPathNode(CopiedPathNode); + ProjectForm.NewPathNode(CopiedItem.PathNode); } private void ClonePathNode() { @@ -5609,14 +5389,13 @@ namespace CodeWalker } private void CopyNavPoly() { - CopiedNavPoly = SelectedItem.NavPoly; - ToolbarPasteButton.Enabled = (CopiedNavPoly != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.NavPoly != null) && ToolbarAddItemButton.Enabled; } private void PasteNavPoly() { - if (CopiedNavPoly == null) return; + if (CopiedItem.NavPoly == null) return; if (ProjectForm == null) return; - ProjectForm.NewNavPoly(CopiedNavPoly); + ProjectForm.NewNavPoly(CopiedItem.NavPoly); } private void CloneNavPoly() { @@ -5663,14 +5442,13 @@ namespace CodeWalker } private void CopyNavPoint() { - CopiedNavPoint = SelectedItem.NavPoint; - ToolbarPasteButton.Enabled = (CopiedNavPoint != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.NavPoint != null) && ToolbarAddItemButton.Enabled; } private void PasteNavPoint() { - if (CopiedNavPoint == null) return; + if (CopiedItem.NavPoint == null) return; if (ProjectForm == null) return; - ProjectForm.NewNavPoint(CopiedNavPoint); + ProjectForm.NewNavPoint(CopiedItem.NavPoint); } private void CloneNavPoint() { @@ -5717,14 +5495,13 @@ namespace CodeWalker } private void CopyNavPortal() { - CopiedNavPortal = SelectedItem.NavPortal; - ToolbarPasteButton.Enabled = (CopiedNavPortal != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.NavPortal != null) && ToolbarAddItemButton.Enabled; } private void PasteNavPortal() { - if (CopiedNavPortal == null) return; + if (CopiedItem.NavPortal == null) return; if (ProjectForm == null) return; - ProjectForm.NewNavPortal(CopiedNavPortal); + ProjectForm.NewNavPortal(CopiedItem.NavPortal); } private void CloneNavPortal() { @@ -5771,14 +5548,13 @@ namespace CodeWalker } private void CopyTrainNode() { - CopiedTrainNode = SelectedItem.TrainTrackNode; - ToolbarPasteButton.Enabled = (CopiedTrainNode != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.TrainTrackNode != null) && ToolbarAddItemButton.Enabled; } private void PasteTrainNode() { - if (CopiedTrainNode == null) return; + if (CopiedItem.TrainTrackNode == null) return; if (ProjectForm == null) return; - ProjectForm.NewTrainNode(CopiedTrainNode); + ProjectForm.NewTrainNode(CopiedItem.TrainTrackNode); } private void CloneTrainNode() { @@ -5825,14 +5601,13 @@ namespace CodeWalker } private void CopyScenarioNode() { - CopiedScenarioNode = SelectedItem.ScenarioNode; - ToolbarPasteButton.Enabled = (CopiedScenarioNode != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.ScenarioNode != null) && ToolbarAddItemButton.Enabled; } private void PasteScenarioNode() { - if (CopiedScenarioNode == null) return; + if (CopiedItem.ScenarioNode == null) return; if (ProjectForm == null) return; - ProjectForm.NewScenarioNode(CopiedScenarioNode); + ProjectForm.NewScenarioNode(CopiedItem.ScenarioNode); } private void CloneScenarioNode() { @@ -5878,14 +5653,13 @@ namespace CodeWalker } private void CopyAudioZone() { - CopiedAudio = SelectedItem.Audio; - ToolbarPasteButton.Enabled = (CopiedAudio != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.Audio != null) && ToolbarAddItemButton.Enabled; } private void PasteAudioZone() { - if (CopiedAudio == null) return; + if (CopiedItem.Audio == null) return; if (ProjectForm == null) return; - ProjectForm.NewAudioZone(CopiedAudio); + ProjectForm.NewAudioZone(CopiedItem.Audio); } private void CloneAudioZone() { @@ -5931,14 +5705,13 @@ namespace CodeWalker } private void CopyAudioEmitter() { - CopiedAudio = SelectedItem.Audio; - ToolbarPasteButton.Enabled = (CopiedAudio != null) && ToolbarAddItemButton.Enabled; + ToolbarPasteButton.Enabled = (CopiedItem.Audio != null) && ToolbarAddItemButton.Enabled; } private void PasteAudioEmitter() { - if (CopiedAudio == null) return; + if (CopiedItem.Audio == null) return; if (ProjectForm == null) return; - ProjectForm.NewAudioEmitter(CopiedAudio); + ProjectForm.NewAudioEmitter(CopiedItem.Audio); } private void CloneAudioEmitter() { @@ -7675,6 +7448,16 @@ namespace CodeWalker NewYmap(); } + private void ToolbarNewYtypButton_Click(object sender, EventArgs e) + { + NewYtyp(); + } + + private void ToolbarNewYbnButton_Click(object sender, EventArgs e) + { + NewYbn(); + } + private void ToolbarNewYndButton_Click(object sender, EventArgs e) { NewYnd(); @@ -7705,6 +7488,16 @@ namespace CodeWalker OpenYmap(); } + private void ToolbarOpenYtypButton_Click(object sender, EventArgs e) + { + OpenYtyp(); + } + + private void ToolbarOpenYbnButton_Click(object sender, EventArgs e) + { + OpenYbn(); + } + private void ToolbarOpenYndButton_Click(object sender, EventArgs e) { OpenYnd(); diff --git a/WorldForm.resx b/WorldForm.resx index 70dd9c9..6d77b39 100644 --- a/WorldForm.resx +++ b/WorldForm.resx @@ -240,25 +240,6 @@ ufo YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB4SURBVDhP3ZC7DcAgDEQZKTMwHOvSIFriS7BlEB+HMic9 QJbvFThLUkpXzjkSpaeuzMPlEELx3jdsBauyCHBY6UWYPQI93KEljQD3jL6EGzN6x0bASyNYwkKU8Udm gd6TMnIikDJyIqjVNz8T7FgKrAwFX6lVinM3aJ05lWDPRRcAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAAHRJREFUOE/tk0EKgCAQRedIncGrGZ602lowuFW/kM1ElLYLEh668D1dKO2DmYcQ - gs/EHpTsnIvGmGZKQMrWjnH12y3ztJR9NfBGxiwD6lpPQEYMaxU4n3aF3PcHPh/AY8Ljy67vDkgZ36AG - WlEyBgKdHDIRJSPcKxCRg0UPAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - xAAADsQBlSsOGwAAAThJREFUOE+dk01ugzAQhTlBj+MDIJC4A1yEa7DMnlWaSiAu0ZI7BNi0XaRpF7Bg - 4/pzbMsQ0qod6SX2zHvPP4yDdUzTJBR2CieF2YAxOWFot6GKDwrlMAyyKAqZZZkMw1AjTVOdowYHrpFd - w4if67p2os/L1wI2DwfuwkRNSitu2+NdA1szJqUVC7ZGYb9/dOQtA/6bptFjcxyBwY7zkfwL0KDF4ESC - 7bHCx/miCf7qYJ1jjjYYx3Fm0nfDXfJWzhjMzuBweJJvr++b5K1dOQN7hP9AH0H96EvM83zh7q+2zsH1 - L1H0fS+TJHEX+ZsBXDRobS/oRorjWB5/aqSXVkZRJKuqQnxtJEJNXCvjTu9D9kGOmhEvW5kwJiVb43wI - WBXYx9R1nV75RuyHKrrnzCcGjE1u9ZyD4BugoZigQ9xrngAAAABJRU5ErkJggg== @@ -267,34 +248,6 @@ ufo YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAB0SURBVDhP7ZNBCoAgEEXnSJ3BqxmetNpaMLhVv5DNRJS2 CxIeuvA9XSjtg5mHEILPxB6U7JyLxphmSkDK1o5x9dst87SUfTXwRsYsA+paT0BGDGsVOJ92hdz3Bz4f wGPC48uu7w5IGd+gBlpRMgYCnRwyESUj3CsQkYNFDwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m - dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADMSURBVDhPrZLBDcMgDEUzGxN0ilyZJ92DqXJoe4Cr - y3f8EXERUptaehVx/F8gzSIil1hKKWIMB8C0EA4hTCXToqCXVFbjOwElKSUF65zzzUbHhad4CYkxyr7v - KvHHIhQ0ybbd5fl4KVhDgns+SPSnDqzYMgQME/TsOO2d/EVQ17ozXmgD2/VHgMCGdY5h9psALwovDBLc - 9GAYcwyzZ//FUZCgiS3btj8k/tqiR3Xn0w+pDp2e2IN+xZJWncAzDINTTQSAwRYGLfQbsrwBmeh5Q8G/ - p8gAAAAASUVORK5CYII= - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - wwAADsMBx2+oZAAAAH5JREFUOE+9kEEKwCAMBH2bL+hPfI/9ooe2B71aVpKS5iBB0i4MyCZZjcFdrbUu - IdsuDMUYB/8H1Fo3HQCPynOhsZTSU0pPAM7wpiG4hcFAzns/j2uAMzzZo3ntDHiYkTWNXwCztAJr+ROl - 0IhU+UTzMEsHkG2XS4CE7K8Uwg0o2F4o9CrlEwAAAABJRU5ErkJggg== - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m - dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADLSURBVDhPpZHRDcIwDEQzWxbqGEjZoOzRqfoBfLS/ - Jnf1IWMKAmrpSYl7d3HSYmaHKOu6msNG2BOKPhVEtdZHiPbqfR0QQqy1Rn4OUMg0TQTrZVlOLt2vLnoJ - EcMw2DzPDMEke9AsYBrHs10vN4I1QqImwwDcFyMjQGaBHr5Bo8nEoYCnCQTGzVeI4oj6fIi+KHgoPBhC - 4knCjTww9vxfbIUQNDEyiGIZ8t6tW/k0vC/AOpuiueNOLwVkUeylvju9FJCg8E1vM/2PlTv5UoervVTJ - uQAAAABJRU5ErkJggg== @@ -389,6 +342,64 @@ ufo 4BJN+IjGo5O8ZJndGVhKxpjWWts551aih0fre+0BLaVchRAezPB2NXSSV/gVwXGYPJiVUt6ns1ghCDjn UQG86w3FToVgDcWCWS9Fvi/Ao0RVAcwUjwpyhzmf4n8BFApS5HZRwRuONGMbrIJ1JIN8O2QAAAAASUVO RK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 + YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG + WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM + TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G + UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC + ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2 + 5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAAAHRJREFUOE/tk0EKgCAQRedIncGrGZ602lowuFW/kM1ElLYLEh668D1dKO2DmYcQ + gs/EHpTsnIvGmGZKQMrWjnH12y3ztJR9NfBGxiwD6lpPQEYMaxU4n3aF3PcHPh/AY8Ljy67vDkgZ36AG + WlEyBgKdHDIRJSPcKxCRg0UPAAAAAElFTkSuQmCC + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + xAAADsQBlSsOGwAAAThJREFUOE+dk01ugzAQhTlBj+MDIJC4A1yEa7DMnlWaSiAu0ZI7BNi0XaRpF7Bg + 4/pzbMsQ0qod6SX2zHvPP4yDdUzTJBR2CieF2YAxOWFot6GKDwrlMAyyKAqZZZkMw1AjTVOdowYHrpFd + w4if67p2os/L1wI2DwfuwkRNSitu2+NdA1szJqUVC7ZGYb9/dOQtA/6bptFjcxyBwY7zkfwL0KDF4ESC + 7bHCx/miCf7qYJ1jjjYYx3Fm0nfDXfJWzhjMzuBweJJvr++b5K1dOQN7hP9AH0H96EvM83zh7q+2zsH1 + L1H0fS+TJHEX+ZsBXDRobS/oRorjWB5/aqSXVkZRJKuqQnxtJEJNXCvjTu9D9kGOmhEvW5kwJiVb43wI + WBXYx9R1nV75RuyHKrrnzCcGjE1u9ZyD4BugoZigQ9xrngAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m + dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADMSURBVDhPrZLBDcMgDEUzGxN0ilyZJ92DqXJoe4Cr + y3f8EXERUptaehVx/F8gzSIil1hKKWIMB8C0EA4hTCXToqCXVFbjOwElKSUF65zzzUbHhad4CYkxyr7v + KvHHIhQ0ybbd5fl4KVhDgns+SPSnDqzYMgQME/TsOO2d/EVQ17ozXmgD2/VHgMCGdY5h9psALwovDBLc + 9GAYcwyzZ//FUZCgiS3btj8k/tqiR3Xn0w+pDp2e2IN+xZJWncAzDINTTQSAwRYGLfQbsrwBmeh5Q8G/ + p8gAAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO + wwAADsMBx2+oZAAAAH5JREFUOE+9kEEKwCAMBH2bL+hPfI/9ooe2B71aVpKS5iBB0i4MyCZZjcFdrbUu + IdsuDMUYB/8H1Fo3HQCPynOhsZTSU0pPAM7wpiG4hcFAzns/j2uAMzzZo3ntDHiYkTWNXwCztAJr+ROl + 0IhU+UTzMEsHkG2XS4CE7K8Uwg0o2F4o9CrlEwAAAABJRU5ErkJggg== + + + + + iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAABl0RVh0U29m + dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADLSURBVDhPpZHRDcIwDEQzWxbqGEjZoOzRqfoBfLS/ + Jnf1IWMKAmrpSYl7d3HSYmaHKOu6msNG2BOKPhVEtdZHiPbqfR0QQqy1Rn4OUMg0TQTrZVlOLt2vLnoJ + EcMw2DzPDMEke9AsYBrHs10vN4I1QqImwwDcFyMjQGaBHr5Bo8nEoYCnCQTGzVeI4oj6fIi+KHgoPBhC + 4knCjTww9vxfbIUQNDEyiGIZ8t6tW/k0vC/AOpuiueNOLwVkUeylvju9FJCg8E1vM/2PlTv5UoervVTJ + uQAAAABJRU5ErkJggg== @@ -424,17 +435,6 @@ ufo rp3fhGJScIRLzKMLFTC9cMIu3nCDVUyjB6WkYA93mEWbAyH9cMImPuA+rWMA31YwBU82kF6BS32Er/aO M8zAh+OEghpcwQ2bg3uwBW8ewFd7xQkm0IA4oaAS7bh2KHjBIZbhV/D6GJkFphrdcIP8lFrAGPwPOjCO QdQiTqrAWNICd7gPnUj+xBKaU9dxfhTkjwV/FxU+AbsiGnc46OYIAAAAAElFTkSuQmCC - - - - - iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 - YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEvSURBVDhP3dK/K0dRGMfxKxRJopCSEkLya/guUhQRmQwG - WfwIkYySgYUSKUKJlOK/MBoMFMofYLUIsfJ+f3NuF3+A8tRree5zP/fcc070f6oHT/jAPTqQj6WvXvCM - TZQgG3H58gFGcYVLtGIN15jBNDbwiGNUIg4pQx8GsQuHhrCDW8yjHyns4Q0DcCXpykM5bFzgHGPYxw1G - UIVMtMHfWUUj4nIg/KurGIYrSAZYOXDGlbhXcZlegUO8Yxzb+BlQAwNW0G0jVAYK0AwHtnCEOyQDZvGC - ObTbKIIvLMA9WIYDizhFMsDjfsAZptCA9JcdfoVBvryOSbgCe4HPTuCz+BQMKEUvJmCy96ET1ehCuAf2 - 5ZF+uwdZKEYtmuBGFSIXhtejBe5PHX7dxL+qKPoEppRHcXOtiDsAAAAASUVORK5CYII=