mirror of
https://gitgud.io/AbstractConcept/rimworld-animation-studio.git
synced 2024-08-15 00:43:27 +00:00
Code refactor
This commit is contained in:
parent
757badf4f6
commit
a55ba7b95b
232 changed files with 1282 additions and 936 deletions
|
@ -36,60 +36,60 @@ namespace RimWorldAnimationStudio
|
|||
[XmlIgnore] public List<string> DefNames
|
||||
{
|
||||
get { return defNames.NullOrEmpty() ? defNames = new List<string>() : defNames; }
|
||||
set { defNames = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); }
|
||||
set { defNames = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<string> BodyDefTypes
|
||||
{
|
||||
get { return bodyDefTypes.NullOrEmpty() ? bodyDefTypes = new List<string>() : bodyDefTypes; }
|
||||
set { bodyDefTypes = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); }
|
||||
set { bodyDefTypes = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<string> RequiredGenitals
|
||||
{
|
||||
get { return requiredGenitals.NullOrEmpty() ? requiredGenitals = new List<string>() : requiredGenitals; }
|
||||
set { requiredGenitals = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); }
|
||||
set { requiredGenitals = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<PawnRaceOffset> RaceOffsets {
|
||||
get { return raceOffsets.NullOrEmpty() ? raceOffsets = new List<PawnRaceOffset>() : raceOffsets; }
|
||||
set { raceOffsets = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); }
|
||||
set { raceOffsets = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<string> Tags
|
||||
{
|
||||
get { return tags.NullOrEmpty() ? tags = new List<string>() : tags; }
|
||||
set { tags = value.NotNullOrEmpty() ? value : null; EventsManager.OnActorChanged(this); }
|
||||
set { tags = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public BodyTypeOffset BodyTypeOffset
|
||||
{
|
||||
get { return bodyTypeOffset == null ? bodyTypeOffset = new BodyTypeOffset() : bodyTypeOffset; }
|
||||
set { bodyTypeOffset = value; EventsManager.OnActorChanged(this); }
|
||||
set { bodyTypeOffset = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool Initiator
|
||||
{
|
||||
get { return initiator == true; }
|
||||
set { if (value) { initiator = true; } else initiator = null; EventsManager.OnActorChanged(this); }
|
||||
set { if (value) { initiator = true; } else initiator = null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool ControlGenitalAngle
|
||||
{
|
||||
get { return controlGenitalAngle == true; }
|
||||
set { if (value) { controlGenitalAngle = true; } else controlGenitalAngle = null; EventsManager.OnActorChanged(this); }
|
||||
set { if (value) { controlGenitalAngle = true; } else controlGenitalAngle = null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool IsFucking
|
||||
{
|
||||
get { return isFucking == true; }
|
||||
set { if (value) { isFucking = true; } else isFucking = null; EventsManager.OnActorChanged(this); }
|
||||
set { if (value) { isFucking = true; } else isFucking = null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool IsFucked
|
||||
{
|
||||
get { return isFucked == true; }
|
||||
set { if (value) { isFucked = true; } else isFucked = null; EventsManager.OnActorChanged(this); }
|
||||
set { if (value) { isFucked = true; } else isFucked = null; }
|
||||
}
|
||||
|
||||
// Local data
|
||||
|
@ -163,6 +163,16 @@ namespace RimWorldAnimationStudio
|
|||
return Workspace.animationDef.Actors.IndexOf(this);
|
||||
}
|
||||
|
||||
public ActorPosition GetCurrentPosition()
|
||||
{
|
||||
return GetPositionAtTick(Workspace.StageTick);
|
||||
}
|
||||
|
||||
public ActorPosition GetPositionAtTick(int atTick)
|
||||
{
|
||||
return new ActorPosition(GetActorID(), atTick);
|
||||
}
|
||||
|
||||
// Pre-save / post-load
|
||||
public void OnPreSave()
|
||||
{
|
||||
|
|
|
@ -28,31 +28,31 @@ namespace RimWorldAnimationStudio
|
|||
[XmlIgnore] public int AnchoringActor
|
||||
{
|
||||
get { return anchoringActor.HasValue ? anchoringActor.Value : 0; }
|
||||
set { anchoringActor = value; EventsManager.OnActorAddonChanged(this); }
|
||||
set { anchoringActor = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public string AnchorName
|
||||
{
|
||||
get { return anchorName; }
|
||||
set { anchorName = value; EventsManager.OnActorAddonChanged(this); }
|
||||
set { anchorName = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public string Layer
|
||||
{
|
||||
get { return layer; }
|
||||
set { layer = value; EventsManager.OnActorAddonChanged(this); }
|
||||
set { layer = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float Scale
|
||||
{
|
||||
get { return scale.HasValue ? scale.Value : 0f; }
|
||||
set { scale = value; EventsManager.OnActorAddonChanged(this); }
|
||||
set { scale = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool Render
|
||||
{
|
||||
get { return render == true; }
|
||||
set { render = value; EventsManager.OnActorAddonChanged(this); }
|
||||
set { render = value; }
|
||||
}
|
||||
|
||||
// Simple curves
|
||||
|
|
|
@ -23,19 +23,19 @@ namespace RimWorldAnimationStudio
|
|||
[XmlIgnore] public float PosX
|
||||
{
|
||||
get { return posX.HasValue ? posX.Value : 0f; }
|
||||
set { posX = value; EventsManager.OnAddonKeyframeChanged(this); }
|
||||
set { posX = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float PosZ
|
||||
{
|
||||
get { return posZ.HasValue ? posZ.Value : 0f; }
|
||||
set { posZ = value; EventsManager.OnAddonKeyframeChanged(this); }
|
||||
set { posZ = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float Rotation
|
||||
{
|
||||
get { return rotation.HasValue ? rotation.Value : 0f; }
|
||||
set { rotation = value; EventsManager.OnAddonKeyframeChanged(this); }
|
||||
set { rotation = value; }
|
||||
}
|
||||
|
||||
// Constructors
|
||||
|
|
|
@ -28,37 +28,37 @@ namespace RimWorldAnimationStudio
|
|||
[XmlIgnore] public string DefName
|
||||
{
|
||||
get { return defName != null && defName != "" ? defName : "newAnimation"; }
|
||||
set { defName = value; EventsManager.OnAnimationDefChanged(); }
|
||||
set { defName = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public string Label
|
||||
{
|
||||
get { return label != null && label != "" ? label : "newAnimation"; }
|
||||
set { label = value; EventsManager.OnAnimationDefChanged(); }
|
||||
set { label = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<string> SexTypes
|
||||
{
|
||||
get { return sexTypes.NullOrEmpty() ? sexTypes = new List<string>() : sexTypes; }
|
||||
set { sexTypes = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); }
|
||||
set { sexTypes = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<string> InteractionDefTypes
|
||||
{
|
||||
get { return interactionDefTypes.NullOrEmpty() ? interactionDefTypes = new List<string>() : interactionDefTypes; }
|
||||
set { interactionDefTypes = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); }
|
||||
set { interactionDefTypes = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<Actor> Actors
|
||||
{
|
||||
get { return actors.NullOrEmpty() ? actors = new List<Actor>() : actors; }
|
||||
set { actors = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); }
|
||||
set { actors = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<AnimationStage> AnimationStages
|
||||
{
|
||||
get { if (animationStages.NullOrEmpty()){ animationStages = new List<AnimationStage>(); } return animationStages; }
|
||||
set { animationStages = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationDefChanged(); }
|
||||
set { animationStages = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
// Local data
|
||||
|
@ -83,12 +83,13 @@ namespace RimWorldAnimationStudio
|
|||
Actor actor = new Actor();
|
||||
Actors.Add(actor);
|
||||
|
||||
foreach (AnimationStage stage in Workspace.animationDef.AnimationStages)
|
||||
{ stage.AddAnimationClip(Workspace.animationDef.Actors.Count - 1); }
|
||||
|
||||
Initialize();
|
||||
Workspace.ActorID = Workspace.animationDef.Actors.Count - 1;
|
||||
|
||||
foreach (AnimationStage stage in Workspace.animationDef.AnimationStages)
|
||||
{ stage.AddAnimationClip(Workspace.ActorID); }
|
||||
|
||||
EventsManager.OnActorCountChanged();
|
||||
EventsManager.OnActorCountChanged();
|
||||
Workspace.RecordEvent("Actor addition");
|
||||
}
|
||||
|
||||
|
@ -119,7 +120,9 @@ namespace RimWorldAnimationStudio
|
|||
{ stage.AddAnimationClip(actor.GetActorID()); }
|
||||
|
||||
Initialize();
|
||||
Workspace.StageID = Workspace.animationDef.AnimationStages.Count - 1;
|
||||
|
||||
EventsManager.OnStageCountChanged();
|
||||
Workspace.RecordEvent("Stage addition");
|
||||
}
|
||||
|
||||
|
@ -127,9 +130,11 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
AnimationStage stage = Workspace.GetCurrentAnimationStage().Copy();
|
||||
stage.StageName += " (Clone)";
|
||||
stage.Initialize();
|
||||
|
||||
Workspace.animationDef.AnimationStages.Insert(Workspace.StageID + 1, stage);
|
||||
Initialize();
|
||||
|
||||
EventsManager.OnStageCountChanged();
|
||||
Workspace.RecordEvent("Stage clone");
|
||||
}
|
||||
|
||||
|
@ -154,8 +159,9 @@ namespace RimWorldAnimationStudio
|
|||
}
|
||||
|
||||
AnimationStages.RemoveAt(Workspace.StageID);
|
||||
|
||||
Workspace.StageID--;
|
||||
|
||||
EventsManager.OnStageCountChanged();
|
||||
Workspace.RecordEvent("Stage deletion");
|
||||
}
|
||||
|
||||
|
|
|
@ -10,11 +10,11 @@ namespace RimWorldAnimationStudio
|
|||
public class AnimationStage
|
||||
{
|
||||
// Data to/from animationDef
|
||||
[SerializeField] private string stageName;
|
||||
[SerializeField] private int? playTimeTicks;
|
||||
[SerializeField] private int? playTimeTicksQuick;
|
||||
[SerializeField] private bool? isLooping;
|
||||
[SerializeField, XmlArray("animationClips"), XmlArrayItem("li")] public List<PawnAnimationClip> animationClips;
|
||||
public string stageName;
|
||||
public int? playTimeTicks;
|
||||
public int? playTimeTicksQuick;
|
||||
public bool? isLooping;
|
||||
[XmlArray("animationClips"), XmlArrayItem("li")] public List<PawnAnimationClip> animationClips;
|
||||
|
||||
// Data serialization control
|
||||
public bool ShouldSerializeanimationClips() { return animationClips.NotNullOrEmpty(); }
|
||||
|
@ -22,32 +22,44 @@ namespace RimWorldAnimationStudio
|
|||
// Data helper functions
|
||||
[XmlIgnore] public string StageName
|
||||
{
|
||||
get { return stageName != null && stageName != "" ? stageName : "NewStage"; }
|
||||
set { stageName = value; EventsManager.OnAnimationStageChanged(this); }
|
||||
get { return string.IsNullOrEmpty(stageName) ? stageName = "NewStage" : stageName; }
|
||||
set { stageName = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int PlayTimeTicks
|
||||
{
|
||||
get { return playTimeTicks.HasValue ? playTimeTicks.Value : 0; }
|
||||
set { playTimeTicks = value; EventsManager.OnAnimationStageChanged(this); }
|
||||
set { playTimeTicks = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int PlayTimeTicksQuick
|
||||
{
|
||||
get { return playTimeTicksQuick.HasValue ? playTimeTicksQuick.Value : 0; }
|
||||
set { playTimeTicksQuick = value; EventsManager.OnAnimationStageChanged(this); }
|
||||
set { playTimeTicksQuick = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool IsLooping
|
||||
{
|
||||
get { return isLooping == true; }
|
||||
set { isLooping = value; EventsManager.OnAnimationStageChanged(this); }
|
||||
set { isLooping = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<PawnAnimationClip> AnimationClips
|
||||
{
|
||||
get { return animationClips.NullOrEmpty() ? animationClips = new List<PawnAnimationClip>() : animationClips; }
|
||||
set { animationClips = value.NotNullOrEmpty() ? value : null; EventsManager.OnAnimationStageChanged(this); }
|
||||
set { animationClips = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int StageLoopsNormal
|
||||
{
|
||||
get { return Mathf.CeilToInt(PlayTimeTicks / Workspace.StageWindowSize); }
|
||||
set { value = Math.Max(1, value); PlayTimeTicks = value * Workspace.StageWindowSize; IsLooping = value > 1; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int StageLoopsQuick
|
||||
{
|
||||
get { return Mathf.CeilToInt(PlayTimeTicksQuick / Workspace.StageWindowSize); }
|
||||
set { value = Math.Max(0, Math.Min(value, StageLoopsNormal)); PlayTimeTicksQuick = value * Workspace.StageWindowSize; IsLooping = value > 1; }
|
||||
}
|
||||
|
||||
// Local data
|
||||
|
@ -63,8 +75,6 @@ namespace RimWorldAnimationStudio
|
|||
if (clip.duration > PlayTimeTicks)
|
||||
{ PlayTimeTicks = clip.duration; }
|
||||
}
|
||||
|
||||
PlayTimeTicksQuick = PlayTimeTicks;
|
||||
}
|
||||
|
||||
public int GetStageID()
|
||||
|
@ -78,7 +88,7 @@ namespace RimWorldAnimationStudio
|
|||
{
|
||||
float scale = (float)newStageWindowSize / Workspace.StageWindowSize;
|
||||
|
||||
foreach (PawnAnimationClip clip in Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips)
|
||||
foreach (PawnAnimationClip clip in AnimationClips)
|
||||
{
|
||||
foreach (PawnKeyframe keyframe in clip.Keyframes)
|
||||
{
|
||||
|
@ -93,8 +103,8 @@ namespace RimWorldAnimationStudio
|
|||
public void ResizeStageWindow(int newStageWindowSize)
|
||||
{
|
||||
Workspace.GetCurrentAnimationStage().stageWindowSize = newStageWindowSize;
|
||||
Workspace.GetCurrentAnimationStage().PlayTimeTicks = newStageWindowSize * Workspace.stageLoopsNormal;
|
||||
Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick = newStageWindowSize * Workspace.stageLoopsQuick;
|
||||
Workspace.GetCurrentAnimationStage().PlayTimeTicks = newStageWindowSize * StageLoopsNormal;
|
||||
Workspace.GetCurrentAnimationStage().PlayTimeTicksQuick = newStageWindowSize * StageLoopsQuick;
|
||||
}
|
||||
|
||||
public void AddAnimationClip(int actorID = -1)
|
||||
|
@ -134,7 +144,7 @@ namespace RimWorldAnimationStudio
|
|||
clip.Keyframes.Add(keyframeB);
|
||||
}
|
||||
|
||||
clip.BuildSimpleCurves();
|
||||
animationClips.Add(clip);
|
||||
}
|
||||
|
||||
// Pre-save / post-load
|
||||
|
|
|
@ -31,20 +31,20 @@ namespace RimWorldAnimationStudio
|
|||
[XmlIgnore] public List<ActorAddon> Addons
|
||||
{
|
||||
get { return addons.NullOrEmpty() ? addons = new List<ActorAddon>() : addons; }
|
||||
set { addons = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnAnimationClipChanged(this); }
|
||||
set { addons = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<PawnKeyframe> Keyframes
|
||||
{
|
||||
get { return keyframes.NullOrEmpty() ? keyframes = new List<PawnKeyframe>() : keyframes; }
|
||||
set { keyframes = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnAnimationClipChanged(this); }
|
||||
set { keyframes = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore]
|
||||
public List<string> Tags
|
||||
{
|
||||
get { return tags.NullOrEmpty() ? tags = new List<string>() : tags; }
|
||||
set { tags = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnAnimationClipChanged(this); }
|
||||
set { tags = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
// Local data
|
||||
|
@ -235,7 +235,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
foreach (PawnKeyframe keyframe in keyframesToClone)
|
||||
{
|
||||
PawnAnimationClip clip = Workspace.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID, out int clipID);
|
||||
PawnAnimationClip clip = Workspace.GetAnimationClipThatOwnsKeyframe(keyframe.keyframeID);
|
||||
|
||||
if (clip == null)
|
||||
{ Debug.LogWarning("Cannot clone pawn keyframe - no clip owns this keyframe"); continue; }
|
||||
|
@ -244,7 +244,7 @@ namespace RimWorldAnimationStudio
|
|||
{ Debug.LogWarning("Cannot clone pawn keyframe - a keyframe already exists at this tick"); return; }
|
||||
|
||||
PawnKeyframe cloneFrame = keyframe.Copy();
|
||||
cloneFrame.GenerateKeyframeID(clipID);
|
||||
cloneFrame.GenerateKeyframeID(clip.GetOwningActorID());
|
||||
cloneFrame.atTick = Workspace.StageTick;
|
||||
|
||||
PawnKeyframe nextKeyframe = clip.Keyframes.FirstOrDefault(x => x.atTick > Workspace.StageTick);
|
||||
|
@ -301,8 +301,8 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
if (Workspace.DoesPawnKeyframeExistAtTick(Workspace.StageID, targetActorID, tickToPasteAt))
|
||||
{
|
||||
PawnKeyframe oldKeyframe = Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[targetActorID].Keyframes.First(x => x.atTick == tickToPasteAt);
|
||||
RemovePawnKeyframe(targetActorID, oldKeyframe.keyframeID, true);
|
||||
PawnKeyframe oldKeyframe = Workspace.GetPawnAnimationClip(targetActorID).Keyframes.First(x => x.atTick == tickToPasteAt);
|
||||
Workspace.GetAnimationClipThatOwnsKeyframe(oldKeyframe.keyframeID).RemovePawnKeyframe(oldKeyframe.keyframeID, true);
|
||||
}
|
||||
|
||||
PawnKeyframe clonedKeyframe = copiedKeyframe.Copy();
|
||||
|
@ -330,34 +330,28 @@ namespace RimWorldAnimationStudio
|
|||
Workspace.RecordEvent("Keyframe pasted");
|
||||
}
|
||||
|
||||
public void RemovePawnKeyframe()
|
||||
public void RemovePawnKeyframe(int keyframeID, bool force = false)
|
||||
{
|
||||
foreach (int keyframeID in Workspace.keyframeID)
|
||||
{
|
||||
if (Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID, out int clipID) != null)
|
||||
{ RemovePawnKeyframe(clipID, keyframeID); }
|
||||
}
|
||||
}
|
||||
|
||||
public void RemovePawnKeyframe(int actorID, int keyframeID, bool force = false)
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetPawnKeyframe(actorID, keyframeID);
|
||||
PawnAnimationClip clip = Workspace.animationDef.AnimationStages[Workspace.StageID].AnimationClips[actorID];
|
||||
|
||||
if (keyframe == null || clip == null) return;
|
||||
PawnKeyframe keyframe = Workspace.GetPawnKeyframe(keyframeID);
|
||||
if (keyframe == null || IsOwnerOfKeyframe(keyframeID) == false) return;
|
||||
|
||||
if (keyframe.atTick == Constants.minTick && force == false)
|
||||
{ Debug.LogWarning("Cannot delete key frame - the first key frame of an animation clip cannot be deleted"); return; }
|
||||
|
||||
if (clip.Keyframes.Count <= 2 && force == false)
|
||||
if (Keyframes.Count <= 2 && force == false)
|
||||
{ Debug.LogWarning("Cannot delete key frame - an animation clip must have two or more keyframes"); return; }
|
||||
|
||||
clip.Keyframes.Remove(keyframe);
|
||||
clip.BuildSimpleCurves();
|
||||
Keyframes.Remove(keyframe);
|
||||
BuildSimpleCurves();
|
||||
|
||||
Workspace.RecordEvent("Keyframe deletion");
|
||||
}
|
||||
|
||||
public bool IsOwnerOfKeyframe(int keyframeID)
|
||||
{
|
||||
return Keyframes.Any(x => x.keyframeID == keyframeID);
|
||||
}
|
||||
|
||||
public float GetStageTickPercentage()
|
||||
{
|
||||
return (float)(Workspace.StageTick % duration) / duration;
|
||||
|
|
|
@ -40,79 +40,79 @@ namespace RimWorldAnimationStudio
|
|||
[XmlIgnore] public float BodyAngle
|
||||
{
|
||||
get { return bodyAngle.HasValue ? bodyAngle.Value : 0f; }
|
||||
set { bodyAngle = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { bodyAngle = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float HeadAngle
|
||||
{
|
||||
get { return headAngle.HasValue ? headAngle.Value : (float)(headAngle = 0f); }
|
||||
set { headAngle = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { headAngle = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float HeadBob
|
||||
{
|
||||
get { return headBob.HasValue ? headBob.Value : (float)(headBob = 0f); }
|
||||
set { headBob = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { headBob = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float BodyOffsetX
|
||||
{
|
||||
get { return bodyOffsetX.HasValue ? bodyOffsetX.Value : (float)(bodyOffsetX = 0f); }
|
||||
set { bodyOffsetX = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { bodyOffsetX = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float BodyOffsetZ
|
||||
{
|
||||
get { return bodyOffsetZ.HasValue ? bodyOffsetZ.Value : (float)(bodyOffsetZ = 0f); }
|
||||
set { bodyOffsetZ = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { bodyOffsetZ = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int HeadFacing
|
||||
{
|
||||
get { return headFacing.HasValue ? headFacing.Value : (int)(headFacing = 2); }
|
||||
set { headFacing = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { headFacing = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int BodyFacing
|
||||
{
|
||||
get { return bodyFacing.HasValue ? bodyFacing.Value : (int)(bodyFacing = 2); }
|
||||
set { bodyFacing = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { bodyFacing = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public float GenitalAngle
|
||||
{
|
||||
get { return genitalAngle.HasValue ? genitalAngle.Value : (float)(genitalAngle = 0f); }
|
||||
set { genitalAngle = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { genitalAngle = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public bool Quiver
|
||||
{
|
||||
get { return quiver == true; }
|
||||
set { quiver = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { quiver = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public int TickDuration
|
||||
{
|
||||
get { return tickDuration.HasValue ? tickDuration.Value : (int)(tickDuration = 0); }
|
||||
set { tickDuration = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { tickDuration = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public string SoundEffect
|
||||
{
|
||||
get { return soundEffect; }
|
||||
set { soundEffect = value; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { soundEffect = value; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<string> Tags
|
||||
{
|
||||
get { return tags.NullOrEmpty() ? tags = new List<string>() : tags; }
|
||||
set { tags = value.NotNullOrEmpty() ? value : null; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { tags = value.NotNullOrEmpty() ? value : null; }
|
||||
}
|
||||
|
||||
[XmlIgnore] public List<AddonKeyframe> AddonKeyframes
|
||||
{
|
||||
get { return addonKeyframes.NullOrEmpty() ? addonKeyframes = new List<AddonKeyframe>() : addonKeyframes; }
|
||||
set { addonKeyframes = value.NotNullOrEmpty()? value : null; EventsManager.OnPawnKeyframeChanged(this); }
|
||||
set { addonKeyframes = value.NotNullOrEmpty()? value : null; }
|
||||
}
|
||||
|
||||
// Local data
|
||||
|
@ -148,6 +148,63 @@ namespace RimWorldAnimationStudio
|
|||
return AddonKeyframes.FirstOrDefault(x => x.AddonName == addonName);
|
||||
}
|
||||
|
||||
public void AdjustActor(Vector2 deltaOffset)
|
||||
{
|
||||
float deltaAngle = -deltaOffset.x * 33.3333f + deltaOffset.y * 33.3333f;
|
||||
int facing = deltaOffset.x < 0 ? 3 : deltaOffset.y < 0 ? 2 : deltaOffset.x > 0 ? 1 : 0;
|
||||
|
||||
switch (Workspace.actorManipulationMode)
|
||||
{
|
||||
case ActorManipulationMode.Pan: MoveActor(deltaOffset); break;
|
||||
case ActorManipulationMode.Rotate: RotateActor(deltaAngle); break;
|
||||
case ActorManipulationMode.Face: FaceActor(facing); break;
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveActor(Vector2 deltaOffset)
|
||||
{
|
||||
if (Workspace.selectedBodyPart == null)
|
||||
{
|
||||
BodyOffsetX += deltaOffset.x;
|
||||
BodyOffsetZ += deltaOffset.y;
|
||||
}
|
||||
|
||||
else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "head")
|
||||
{ HeadBob += deltaOffset.y; }
|
||||
|
||||
Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
|
||||
Workspace.RecordEvent("Actor position / orientation");
|
||||
}
|
||||
|
||||
public void RotateActor(float deltaAngle)
|
||||
{
|
||||
if (Workspace.selectedBodyPart == null)
|
||||
{ BodyAngle += deltaAngle; }
|
||||
|
||||
else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "head")
|
||||
{ HeadAngle += deltaAngle; }
|
||||
|
||||
else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "appendage")
|
||||
{ GenitalAngle -= deltaAngle; }
|
||||
|
||||
Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
|
||||
Workspace.RecordEvent("Actor position / orientation");
|
||||
}
|
||||
|
||||
public void FaceActor(int facing)
|
||||
{
|
||||
PawnKeyframe keyframe = Workspace.GetCurrentPawnKeyframe(true);
|
||||
|
||||
if (Workspace.selectedBodyPart == null)
|
||||
{ keyframe.BodyFacing = facing; }
|
||||
|
||||
else if (Workspace.selectedBodyPart.bodyPart.ToLower() == "head")
|
||||
{ keyframe.HeadFacing = facing; }
|
||||
|
||||
Workspace.GetCurrentPawnAnimationClip().BuildSimpleCurves();
|
||||
Workspace.RecordEvent("Actor position / orientation");
|
||||
}
|
||||
|
||||
// Pre-save / post-load
|
||||
public void OnPreSave()
|
||||
{
|
||||
|
@ -157,7 +214,7 @@ namespace RimWorldAnimationStudio
|
|||
|
||||
foreach (AddonKeyframe addonKeyframe in AddonKeyframes)
|
||||
{
|
||||
ActorAddon addon = Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID, out int clipID).GetActorAddon(addonKeyframe.AddonName);
|
||||
ActorAddon addon = Workspace.GetAnimationClipThatOwnsKeyframe(keyframeID).GetActorAddon(addonKeyframe.AddonName);
|
||||
|
||||
if (addon.Render)
|
||||
{ addonKeyframes.Add(addonKeyframe.Copy()); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue