Def load selection and basic def alteration

This commit is contained in:
AbstractConcept 2022-09-15 00:17:44 -05:00
parent f78d85de3b
commit 0364322d46
311 changed files with 15823 additions and 1151 deletions

View file

@ -12,10 +12,8 @@ namespace RimWorldAnimationStudio
public InputField bodyOffsetXField;
public InputField bodyOffsetZField;
public Toggle initiatorToggle;
public GameObject bodyPartsTags;
private AnimationDef animationDef;
private int actorID = 0;
private Actor actor;
public string bodyType
{
@ -28,25 +26,49 @@ namespace RimWorldAnimationStudio
}
}
public void Initialize(AnimationDef animationDef, int actorID)
public void Initialize(Actor actor)
{
this.animationDef = animationDef;
this.actorID = actorID;
this.actor = actor;
UpdateBodyType();
initiatorToggle.isOn = animationDef.actors[actorID].initiator;
}
public void UpdateBodyType()
{
bodyOffsetXField.text = animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType).x.ToString();
bodyOffsetZField.text = animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType).z.ToString();
initiatorToggle.isOn = actor.initiator;
bodyOffsetXField.text = actor.bodyTypeOffset.GetOffset(bodyType).x.ToString();
bodyOffsetZField.text = actor.bodyTypeOffset.GetOffset(bodyType).z.ToString();
}
public void UpdateAnimationDef()
{
animationDef.actors[actorID].initiator = initiatorToggle.isOn;
animationDef.actors[actorID].bodyTypeOffset.SetOffset(bodyType, new Vector2(float.Parse(bodyOffsetXField.text), float.Parse(bodyOffsetZField.text)));
float.TryParse(bodyOffsetXField.text, out float x);
float.TryParse(bodyOffsetZField.text, out float z);
actor.bodyTypeOffset.SetOffset(bodyType, new Vector2(x, z));
actor.initiator = initiatorToggle.isOn;
if (actor.isFucking == null)
{ }
}
public void OpenSelectBodyPartsDialog()
{
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectBodyPartsDialog)) as SelectBodyPartsDialog[];
if (dialog != null)
{ dialog[0].Initialize(actor); dialog[0].Pop(); }
}
public void OpenSelectDefNamesDialog()
{
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectDefNamesDialog)) as SelectDefNamesDialog[];
if (dialog != null)
{ dialog[0].Initialize(actor); dialog[0].Pop(); }
}
public void OpenSelectBodyDefTypesDialog()
{
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectBodyDefTypesDialog)) as SelectBodyDefTypesDialog[];
if (dialog != null)
{ dialog[0].Initialize(actor); dialog[0].Pop(); }
}
}
}

View file

@ -7,19 +7,31 @@ namespace RimWorldAnimationStudio
{
public class Actor
{
public List<string> defNames = new List<string>();
public List<string> requiredGenitals = new List<string>();
public bool controlGenitalAngle = false;
public List<AlienRaceOffset> raceOffsets;
public List<string> blacklistedRaces;
public bool initiator = false;
[XmlArray("defNames"), XmlArrayItem("li")] public List<string> defNames = new List<string>();
[XmlArray("bodyDefTypes"), XmlArrayItem("li")] public List<string> bodyDefTypes = new List<string>();
[XmlArray("requiredGender"), XmlArrayItem("li")] public List<string> requiredGender = new List<string>();
[XmlArray("requiredGenitals"), XmlArrayItem("li")] public List<string> requiredGenitals = new List<string>();
[XmlArray("raceOffsets"), XmlArrayItem("li")] public List<AlienRaceOffset> raceOffsets = new List<AlienRaceOffset>();
[XmlArray("blacklistedRaces"), XmlArrayItem("li")] public List<string> blacklistedRaces = new List<string>();
[XmlArray("tags"), XmlArrayItem("li")] public List<string> tags;
public string gender;
public bool isFucking = false;
public bool isFucked = false;
public List<string> bodyDefTypes = new List<string>();
public BodyTypeOffset bodyTypeOffset = new BodyTypeOffset();
public Vector3 offset = new Vector2(0, 0);
public List<string> requiredGender;
public List<string> tags = new List<string>();
public bool initiator = false;
public bool? controlGenitalAngle;
public bool? isFucking;
public bool? isFucked;
public bool ShouldSerializedefNames() { return defNames.NotNullOrEmpty(); }
public bool ShouldSerializebodyDefTypes() { return bodyDefTypes.NotNullOrEmpty(); }
public bool ShouldSerializerequiredGender() { return requiredGender.NotNullOrEmpty(); }
public bool ShouldSerializerequiredGenitals() { return requiredGenitals.NotNullOrEmpty(); }
public bool ShouldSerializeraceOffsets() { return raceOffsets.NotNullOrEmpty(); }
public bool ShouldSerializeblacklistedRaces() { return blacklistedRaces.NotNullOrEmpty(); }
public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); }
public bool ShouldSerializecontrolGenitalAngle() { return controlGenitalAngle != null; }
public bool ShouldSerializeisFucking() { return isFucking != null; }
public bool ShouldSerializeisFucked() { return isFucked != null; }
}
}

View file

@ -6,13 +6,14 @@ namespace RimWorldAnimationStudio
{
public abstract class AnimationClip
{
[XmlIgnore]
public Dictionary<int, string> SoundEffects = new Dictionary<int, string>();
public List<string> types;
public int duration;
public string layer = "Pawn";
public List<string> tags;
[XmlIgnore] public int duration;
[XmlIgnore] public Dictionary<int, string> SoundEffects = new Dictionary<int, string>();
public abstract void BuildSimpleCurves();
public string soundDef = null;
public int actor;
public List<string> tags = new List<string>();
public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); }
}
}

View file

@ -7,10 +7,7 @@ namespace RimWorldAnimationStudio
public class PawnAnimationClip : AnimationClip
{
[XmlAttribute("Class")] public string className = "Rimworld_Animations.PawnAnimationClip";
[XmlArray("keyframes"), XmlArrayItem("li")] public List<PawnKeyframe> keyframes = new List<PawnKeyframe>();
public AltitudeLayer layer = AltitudeLayer.Pawn;
[XmlIgnore] public Dictionary<int, bool> quiver = new Dictionary<int, bool>();
[XmlIgnore] public SimpleCurve GenitalAngle = new SimpleCurve();
@ -36,70 +33,39 @@ namespace RimWorldAnimationStudio
{
if (frame.atTick.HasValue)
{
if (frame.bodyAngle.HasValue)
BodyAngle.Add((float)frame.atTick / (float)duration, frame.bodyAngle.Value, true);
if (frame.headAngle.HasValue)
HeadAngle.Add((float)frame.atTick / (float)duration, frame.headAngle.Value, true);
if (frame.bodyOffsetX.HasValue)
BodyOffsetX.Add((float)frame.atTick / (float)duration, frame.bodyOffsetX.Value, true);
if (frame.bodyOffsetZ.HasValue)
BodyOffsetZ.Add((float)frame.atTick / (float)duration, frame.bodyOffsetZ.Value, true);
if (frame.headFacing.HasValue)
HeadFacing.Add((float)frame.atTick / (float)duration, frame.headFacing.Value, true);
if (frame.bodyFacing.HasValue)
BodyFacing.Add((float)frame.atTick / (float)duration, frame.bodyFacing.Value, true);
if (frame.headBob.HasValue)
HeadBob.Add((float)frame.atTick / (float)duration, frame.headBob.Value, true);
BodyAngle.Add((float)frame.atTick / (float)duration, frame.bodyAngle, true);
HeadAngle.Add((float)frame.atTick / (float)duration, frame.headAngle, true);
BodyOffsetX.Add((float)frame.atTick / (float)duration, frame.bodyOffsetX, true);
BodyOffsetZ.Add((float)frame.atTick / (float)duration, frame.bodyOffsetZ, true);
HeadFacing.Add((float)frame.atTick / (float)duration, frame.headFacing, true);
BodyFacing.Add((float)frame.atTick / (float)duration, frame.bodyFacing, true);
HeadBob.Add((float)frame.atTick / (float)duration, frame.headBob, true);
if (frame.genitalAngle.HasValue)
GenitalAngle.Add((float)frame.atTick / (float)duration, frame.genitalAngle.Value, true);
{ GenitalAngle.Add((float)frame.atTick / (float)duration, frame.genitalAngle.Value, true); }
if (frame.soundEffect != null)
{
SoundEffects.Add((int)frame.atTick, frame.soundEffect);
}
{ SoundEffects.Add((int)frame.atTick, frame.soundEffect); }
}
else
{
if (frame.bodyAngle.HasValue)
BodyAngle.Add((float)keyframePosition / (float)duration, frame.bodyAngle.Value, true);
if (frame.headAngle.HasValue)
HeadAngle.Add((float)keyframePosition / (float)duration, frame.headAngle.Value, true);
if (frame.bodyOffsetX.HasValue)
BodyOffsetX.Add((float)keyframePosition / (float)duration, frame.bodyOffsetX.Value, true);
if (frame.bodyOffsetZ.HasValue)
BodyOffsetZ.Add((float)keyframePosition / (float)duration, frame.bodyOffsetZ.Value, true);
if (frame.headFacing.HasValue)
HeadFacing.Add((float)keyframePosition / (float)duration, frame.headFacing.Value, true);
if (frame.bodyFacing.HasValue)
BodyFacing.Add((float)keyframePosition / (float)duration, frame.bodyFacing.Value, true);
if (frame.headBob.HasValue)
HeadBob.Add((float)keyframePosition / (float)duration, frame.headBob.Value, true);
BodyAngle.Add((float)keyframePosition / (float)duration, frame.bodyAngle, true);
HeadAngle.Add((float)keyframePosition / (float)duration, frame.headAngle, true);
BodyOffsetX.Add((float)keyframePosition / (float)duration, frame.bodyOffsetX, true);
BodyOffsetZ.Add((float)keyframePosition / (float)duration, frame.bodyOffsetZ, true);
HeadFacing.Add((float)keyframePosition / (float)duration, frame.headFacing, true);
BodyFacing.Add((float)keyframePosition / (float)duration, frame.bodyFacing, true);
HeadBob.Add((float)keyframePosition / (float)duration, frame.headBob, true);
if (frame.genitalAngle.HasValue)
GenitalAngle.Add((float)keyframePosition / (float)duration, frame.genitalAngle.Value, true);
if (frame.soundEffect != null)
{
SoundEffects.Add(keyframePosition, frame.soundEffect);
}
{ SoundEffects.Add(keyframePosition, frame.soundEffect); }
if (frame.tickDuration != 1 && frame.quiver.HasValue)
{
quiver.Add(keyframePosition, true);
quiver.Add(keyframePosition + frame.tickDuration - 1, false);
}

View file

@ -6,10 +6,8 @@ namespace RimWorldAnimationStudio
{
public class ThingAnimationClip : AnimationClip
{
[XmlAttribute("Class")] public string className = "Rimworld_Animations.PawnAnimationClip";
[XmlAttribute("Class")] public string className = "Rimworld_Animations.ThingAnimationClip";
[XmlArray("keyframes"), XmlArrayItem("li")] public List<ThingKeyframe> keyframes = new List<ThingKeyframe>();
public string layer = "Pawn";
[XmlIgnore] public SimpleCurve PositionX = new SimpleCurve();
[XmlIgnore] public SimpleCurve PositionZ = new SimpleCurve();
@ -32,36 +30,22 @@ namespace RimWorldAnimationStudio
{
if (frame.atTick.HasValue)
{
if (frame.positionX.HasValue)
PositionX.Add((float)frame.atTick / (float)duration, frame.positionX.Value, true);
if (frame.positionZ.HasValue)
PositionZ.Add((float)frame.atTick / (float)duration, frame.positionZ.Value, true);
if (frame.rotation.HasValue)
Rotation.Add((float)frame.atTick / (float)duration, frame.rotation.Value, true);
PositionX.Add((float)frame.atTick / (float)duration, frame.positionX, true);
PositionZ.Add((float)frame.atTick / (float)duration, frame.positionZ, true);
Rotation.Add((float)frame.atTick / (float)duration, frame.rotation, true);
if (frame.soundEffect != null)
{
SoundEffects.Add((int)frame.atTick, frame.soundEffect);
}
{ SoundEffects.Add((int)frame.atTick, frame.soundEffect); }
}
else
{
if (frame.positionX.HasValue)
PositionX.Add((float)keyframePosition / (float)duration, frame.positionX.Value, true);
if (frame.positionZ.HasValue)
PositionZ.Add((float)keyframePosition / (float)duration, frame.positionZ.Value, true);
if (frame.rotation.HasValue)
Rotation.Add((float)keyframePosition / (float)duration, frame.rotation.Value, true);
PositionX.Add((float)keyframePosition / (float)duration, frame.positionX, true);
PositionZ.Add((float)keyframePosition / (float)duration, frame.positionZ, true);
Rotation.Add((float)keyframePosition / (float)duration, frame.rotation, true);
if (frame.soundEffect != null)
{
SoundEffects.Add(keyframePosition, frame.soundEffect);
}
{ SoundEffects.Add(keyframePosition, frame.soundEffect); }
keyframePosition += frame.tickDuration;
}

View file

@ -9,12 +9,14 @@ namespace RimWorldAnimationStudio
public string defName = "Undefined";
public string label = "Undefined";
public bool sounds = false;
[XmlIgnore] public int animationTimeTicks = 0;
[XmlArray("sexTypes"), XmlArrayItem("li")] public List<string> sexTypes = new List<string>();
[XmlArray("interactionDefTypes"), XmlArrayItem("li")] public List<string> interactionDefTypes = new List<string>();
[XmlArray("actors"), XmlArrayItem("li")] public List<Actor> actors = new List<Actor>();
[XmlArray("animationStages"), XmlArrayItem("li")] public List<AnimationStage> animationStages = new List<AnimationStage>();
[XmlIgnore] public int animationTimeTicks = 0;
public void Initialize()
{
animationTimeTicks = 0;

View file

@ -12,20 +12,19 @@ namespace RimWorldAnimationStudio
public string Hulk;
public string Fat;
public void SetOffset(string bodyType, Vector2 offset)
public void SetOffset(string bodyType, Vector2 bodyOffset)
{
FieldInfo bodyTypeOffsetInfo = typeof(BodyTypeOffset).GetField(bodyType);
if (bodyTypeOffsetInfo == null)
{ return; }
bodyTypeOffsetInfo.SetValue(this, offset.ToString());
string _bodyOffset = "(" + bodyOffset.x + ", " + bodyOffset.y + ")";
bodyTypeOffsetInfo.SetValue(this, _bodyOffset);
}
public Vector3 GetOffset(string bodyType)
{
Debug.Log(bodyType);
FieldInfo bodyTypeOffsetInfo = typeof(BodyTypeOffset).GetField(bodyType);
if (bodyTypeOffsetInfo == null)

View file

@ -6,9 +6,13 @@ namespace RimWorldAnimationStudio
{
public class Keyframe
{
public int tickDuration = 1;
public float? atTick;
public int tickDuration = 1;
public string soundEffect;
public List<string> tags = new List<string>();
public bool ShouldSerializeatTick() { return atTick != null; }
public bool ShouldSerializetags() { return tags.NotNullOrEmpty(); }
}
}

View file

@ -6,14 +6,18 @@ namespace RimWorldAnimationStudio
{
public class PawnKeyframe : Keyframe
{
public float? bodyAngle;
public float? headAngle;
public float? headBob;
public float? bodyOffsetX;
public float? bodyOffsetZ;
public float? headFacing;
public float? bodyFacing;
public float bodyAngle;
public float headAngle;
public float headBob;
public float bodyOffsetX;
public float bodyOffsetZ;
public float headFacing;
public float bodyFacing;
public float? genitalAngle;
public bool? quiver;
public bool ShouldSerializegenitalAngle() { return genitalAngle != null; }
public bool ShouldSerializequiver() { return quiver != null; }
}
}

View file

@ -6,8 +6,8 @@ namespace RimWorldAnimationStudio
{
public class ThingKeyframe : Keyframe
{
public float? positionX;
public float? positionZ;
public float? rotation;
public float positionX;
public float positionZ;
public float rotation;
}
}

View file

@ -10,121 +10,43 @@ using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class AnimationController : MonoBehaviour
public class AnimationController : Singleton<AnimationController>
{
public Defs defs;
public AnimationDef anim;
public bool isAnimating = false;
public bool isLooping = true;
public int stageTick = 0;
public int stageID = 0;
public bool autoAdvanceToNextStage = false;
//public InputField stageTickField;
//public InputField stageLengthField;
public Slider stageTimelineSlider;
//public InputField stageIDField;
public ActorBody actorBodyPrefab;
public GameObject actorBodyPrefab;
public List<ActorBody> actorBodies = new List<ActorBody>();
//public List<Dropdown> bodyTypeDropdowns = new List<Dropdown>();
public Text stageTickField;
public Text stageLengthField;
public Text stageTickText;
public Text stageLengthText;
public Transform actorCards;
public GameObject actorCardPrefab;
public Dropdown stageLoopDropdown;
public InputField stageIDField;
private float currentTime = 0;
public T ReadDataFromXML<T>(string inputPath)
{
using (StreamReader stringReader = new StreamReader(inputPath))
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
}
public void LoadNewXML(string inputPath)
{
defs = ReadDataFromXML<Defs>(inputPath);
if (defs?.animationDefs != null)
{
Debug.Log(defs.animationDefs.Count);
Debug.Log(defs.animationDefs[0].defName);
anim = defs.animationDefs[0];
InitializeAnimation(anim);
foreach (Actor actor in anim.actors)
{
AddActor();
}
UpdateAnimation();
}
}
public void SaveXML()
{
if (anim == null)
{ return; }
string path = StandaloneFileBrowser.SaveFilePanel("Save file", "", anim.defName + ".xml", ".xml");
if (path == null || path == "")
{ return; }
XmlSerializer writer = new XmlSerializer(typeof(AnimationDef));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
FileStream file = File.Create(path);
writer.Serialize(file, anim, ns);
file.Close();
}
public void OpenFileDialog()
{
var paths = StandaloneFileBrowser.OpenFilePanel("Open File", "", "", false);
Debug.Log(paths[0]);
LoadNewXML(paths[0]);
}
public void PlayAnimation(bool value)
{
isAnimating = value;
}
public void ToggleAnimationLoop()
{
isLooping = !isLooping;
}
public void UpdateStageID(InputField stageIDField)
{
if (anim == null)
{
stageIDField.text = "0";
return;
}
int i = int.Parse(stageIDField.text);
stageID = Mathf.Clamp(i, 0, anim.animationStages.Count - 1);
stageTick = 0;
stageIDField.text = stageID.ToString();
}
public void Update()
{
if (anim == null) { return; }
// No animation, exit
if (Workspace.animationDef == null) { return; }
// Dirty animation, reset
if (Workspace.animationDef != null && Workspace.isDirty)
{ Initialize(); return; }
// Not animating, update preview
if (isAnimating == false) { UpdateAnimation(); return; }
// Animating, update stage tick before updating preview
currentTime += Time.deltaTime;
if (currentTime < 1f/60f)
@ -133,68 +55,47 @@ namespace RimWorldAnimationStudio
currentTime -= 1f/60f;
stageTick += 1;
if (stageTick > anim.animationStages[stageID].playTimeTicks)
int stageLenght = Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks;
if (stageTick > stageLenght)
{
if (isLooping)
if (stageLoopDropdown.value == 1)
{ stageTick = 1; }
else if (autoAdvanceToNextStage && stageID < anim.animationStages.Count - 1)
{ stageTick = 1; stageID++; }
else if (stageLoopDropdown.value == 2 && Workspace.stageID < Workspace.animationDef.animationStages.Count - 1)
{
stageTick = 1;
Workspace.stageID++;
stageIDField.text = Workspace.stageID.ToString();
}
else
{ stageTick = anim.animationStages[stageID].playTimeTicks; }
{ stageTick = stageLenght; }
}
stageTimelineSlider.maxValue = stageLenght;
stageTimelineSlider.value = stageTick;
UpdateAnimation();
}
public void AddActor()
{
GameObject actorCardObject = Instantiate(actorCardPrefab, actorCards);
actorCardObject.GetComponent<ActorCard>().Initialize(anim, actorCards.childCount - 1);
}
public void InitializeAnimation(AnimationDef anim)
{
ResetAnimation();
anim.Initialize();
this.anim = anim;
for (int actorID = 0; actorID < anim.actors.Count; actorID++)
{
ActorBody actorBody = Instantiate(actorBodyPrefab, transform) as ActorBody;
actorBodies.Add(actorBody);
}
}
public void ResetAnimation()
{
anim = null;
stageID = 0;
stageTick = 0;
isAnimating = false;
actorBodies.Clear();
foreach (Transform child in transform)
{ Destroy(child.gameObject); }
}
public void UpdateAnimation()
{
stageTickField.text = stageTick.ToString();
stageLengthField.text = anim.animationStages[stageID].playTimeTicks.ToString();
if (stageTickText != null)
{ stageTickText.text = stageTick.ToString(); }
if (stageLengthText != null)
{ stageLengthText.text = Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks.ToString(); }
for (int actorID = 0; actorID < actorBodies.Count; actorID++)
{
ActorBody actorBody = actorBodies[actorID];
string bodyType = actorCards.transform.GetChild(actorID).GetComponent<ActorCard>().bodyType; //bodyTypeDropdowns[actorID].options[bodyTypeDropdowns[actorID].value].text;
PawnAnimationClip clip = anim.animationStages[stageID].animationClips[actorID];
PawnAnimationClip clip = Workspace.animationDef.animationStages[Workspace.stageID].animationClips[actorID];
float clipPercent = (float)(stageTick % clip.duration) / clip.duration;
Vector3 deltaPos = new Vector3(clip.BodyOffsetX.Evaluate(clipPercent), 0, clip.BodyOffsetZ.Evaluate(clipPercent));
deltaPos += anim.actors[actorID].bodyTypeOffset.GetOffset(bodyType);
deltaPos += Workspace.animationDef.actors[actorID].bodyTypeOffset.GetOffset(bodyType);
float bodyAngle = clip.BodyAngle.Evaluate(clipPercent);
float headAngle = clip.HeadAngle.Evaluate(clipPercent);
@ -222,10 +123,82 @@ namespace RimWorldAnimationStudio
actorBody.bodyRenderer.sprite = Resources.Load<Sprite>("Textures/Humanlike/Bodies/" + bodyType + bodyFacing);
actorBody.headRenderer.sprite = Resources.Load<Sprite>("Textures/Humanlike/Heads/Head" + headFacing);
actorBody.bodyRenderer.sortingLayerName = clip.layer.ToString();
actorBody.headRenderer.sortingLayerName = clip.layer.ToString();
actorBody.bodyRenderer.sortingLayerName = clip.layer;
actorBody.headRenderer.sortingLayerName = clip.layer;
actorBody.headRenderer.sortingOrder = headFacing == 2 ? 1 : -1;
}
}
public void UpdateStageID()
{
if (Workspace.animationDef == null)
{
stageIDField.text = "0";
return;
}
int.TryParse(stageIDField.text, out int i);
Workspace.stageID = Mathf.Clamp(i, 0, Workspace.animationDef.animationStages.Count - 1);
stageTick = 0;
stageIDField.text = Workspace.stageID.ToString();
}
public void Initialize()
{
Debug.Log("Initializing animation preview");
Reset();
for (int actorID = 0; actorID < Workspace.animationDef.actors.Count; actorID++)
{
GameObject actorBodyObject = Instantiate(actorBodyPrefab, transform);
actorBodies.Add(actorBodyObject.GetComponent<ActorBody>());
GameObject actorCardObject = Instantiate(actorCardPrefab, actorCards);
actorCardObject.GetComponent<ActorCard>().Initialize(Workspace.animationDef.actors[actorID]);
}
Workspace.isDirty = false;
UpdateAnimation();
}
public void Reset()
{
Workspace.stageID = 0;
stageTick = 0;
isAnimating = false;
foreach (ActorBody actorBody in actorBodies)
{ Destroy(actorBody.gameObject); }
foreach (Transform actorCard in actorCards)
{ Destroy(actorCard.gameObject); }
actorBodies.Clear();
}
public void ToggleAnimation()
{
isAnimating = !isAnimating;
}
public void ToggleAnimationLoop()
{
isLooping = !isLooping;
}
public void UpdateFromStageTimelineSlider()
{
if (Workspace.animationDef == null)
{ return; }
int stageLenght = Workspace.animationDef.animationStages[Workspace.stageID].playTimeTicks;
if (stageLenght != (int)stageTimelineSlider.value)
{ stageTick = (int)stageTimelineSlider.value; }
}
}
}

View file

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class AnimationDefCard : MonoBehaviour
{
public InputField defNameField;
public InputField labelField;
public Toggle playSoundsToggle;
public void Initialize()
{
defNameField.text = Workspace.animationDef.defName;
labelField.text = Workspace.animationDef.label;
playSoundsToggle.isOn = Workspace.animationDef.sounds;
}
public void UpdateAnimationDef()
{
Workspace.animationDef.defName = defNameField.text;
Workspace.animationDef.label = labelField.text;
Workspace.animationDef.sounds = playSoundsToggle.isOn;
}
public void OpenSelectSexTypesDialog()
{
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectSexTypesDialog)) as SelectSexTypesDialog[];
if (dialog != null)
{ dialog[0].Initialize(); dialog[0].Pop(); }
}
public void OpenSelectInteractionDefsDialog()
{
var dialog = Resources.FindObjectsOfTypeAll(typeof(SelectInteractionDefsDialog)) as SelectInteractionDefsDialog[];
if (dialog != null)
{ dialog[0].Initialize(); dialog[0].Pop(); }
}
}
}

View file

@ -1,5 +1,5 @@
fileFormatVersion: 2
guid: 7a40ab1285a8ce74082b0d1b481d41aa
guid: e1d8f33927e6b4d44914a445362b802d
MonoImporter:
externalObjects: {}
serializedVersion: 2

View file

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
using SFB;
namespace RimWorldAnimationStudio
{
public class ApplicationManager : Singleton<ApplicationManager>
{
public DialogBox exitDialog;
public SelectAnimationDialog selectAnimationDialog;
public void TryToCloseApplication()
{
exitDialog.Pop();
}
public void CloseApplication()
{
Debug.Log("Exiting application");
Application.Quit();
}
public void TryToLoadAnimation()
{
var paths = StandaloneFileBrowser.OpenFilePanel("Open AnimationDef File", "", "xml", false);
if (paths == null || paths.Any() == false)
{ Debug.LogError("Selected file was null or invalid"); return; }
Defs defs = XmlUtility.ReadXML<Defs>(paths[0]);
if (defs?.animationDefs == null)
{ Debug.LogError("Selected file contains no animation data"); return; }
if (defs.animationDefs.Count == 1)
{ LoadAnimation(defs.animationDefs[0]); return; }
selectAnimationDialog.Initialize(defs);
selectAnimationDialog.Pop();
}
public void LoadAnimation(AnimationDef animationDef)
{
Debug.Log("Loaded AnimationDef: " + animationDef.defName);
animationDef.Initialize();
Workspace.animationDef = animationDef;
Workspace.isDirty = true;
var animationDefCards = Resources.FindObjectsOfTypeAll(typeof(AnimationDefCard)) as AnimationDefCard[];
Debug.Log(animationDefCards);
if (animationDefCards != null)
{
animationDefCards[0].Initialize();
animationDefCards[0].gameObject.SetActive(true);
}
}
public void TrySaveAnimation()
{
if (Workspace.animationDef == null)
{ return; }
string defName = Workspace.animationDef.defName != null && Workspace.animationDef.defName != "" ? Workspace.animationDef.defName : "newAnimationDef";
var path = StandaloneFileBrowser.SaveFilePanel("Save AnimationDef File", "", defName, "xml");
if (path != null && path != "")
{ SaveAnimation(path); }
}
public void SaveAnimation(string path)
{
Debug.Log("Saving AnimationDef: " + Workspace.animationDef.defName);
Defs defs = new Defs();
defs.animationDefs.Add(Workspace.animationDef);
XmlUtility.WriteXML(defs, path);
}
public void NewAnimation()
{
return;
AnimationDef animationDef = new AnimationDef();
// Add one stage, add one actor, add one clip, add one frame
Workspace.animationDef = new AnimationDef();
Workspace.isDirty = true;
var animationDefCards = Resources.FindObjectsOfTypeAll(typeof(AnimationDefCard)) as GameObject[];
if (animationDefCards != null)
{ animationDefCards[0].SetActive(true); }
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8c0c094e56b459d42850b3632db6c4ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,99 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace RimWorldAnimationStudio
{
public class CameraController : MonoBehaviour
{
private Camera cam;
[Header("Scroll controls")]
public float scrollSpeed = 100f;
[Header("Zoom controls")]
public float zoom = -5f;
public float minZoom = -3f;
public float maxZoom = -15f;
[Header("Max bounds")]
public float maxBoundsXAxis = 30;
public float maxBoundsYAxis = 30;
private float x;
private float y;
private float curZoom;
private bool mouseDragActive = false;
private Vector3 mouseDragOrigin;
private void Start()
{
x = transform.position.x;
y = transform.position.y;
curZoom = zoom;
transform.position = new Vector3(transform.position.x, transform.position.y, -10);
cam = this.GetComponent<Camera>();
}
private void Update()
{
if (Input.GetMouseButton(2))
{ StartMouseDrag(); }
else if (Input.GetMouseButtonUp(2))
{ ResetMouseDrag(); }
curZoom += Input.GetAxis("Mouse ScrollWheel") * scrollSpeed * 0.1f;
curZoom = Mathf.Clamp(curZoom, maxZoom, minZoom);
x = transform.position.x + Input.GetAxis("Horizontal") * scrollSpeed * Time.deltaTime;
y = transform.position.y + Input.GetAxis("Vertical") * scrollSpeed * Time.deltaTime;
Vector3 cameraPosition = Vector3.Lerp(transform.position, new Vector3(x, y, -10), 0.2f);
transform.position = cameraPosition;
cam.orthographicSize = Mathf.Abs(curZoom);
}
public void SetPosition(Vector3 position)
{
x = position.x;
y = position.y;
transform.position = position;
}
public void SetZoom(float zoom)
{
this.zoom = Mathf.Clamp(zoom, maxZoom, minZoom);
}
public void StartMouseDrag()
{
Vector3 delta = cam.ScreenToWorldPoint(Input.mousePosition) - cam.transform.position;
if (mouseDragActive == false)
{
mouseDragActive = true;
mouseDragOrigin = cam.ScreenToWorldPoint(Input.mousePosition);
}
cam.transform.position = mouseDragOrigin - delta;
}
public void ResetMouseDrag()
{
mouseDragActive = false;
}
public void ResetCamera()
{
cam.transform.position = new Vector3(0, 0, -10);
curZoom = zoom;
mouseDragActive = false;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 192ae5e804d239d42891ba0bdc42e8b6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -1,35 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class DialogBox : MonoBehaviour
{
public Image backSplash;
public void Start()
{
//backSplash = Instanitate(new Image() { SpriteRenderer }, transform);
//SpriteRenderer spriteRenderer = backSplash.GetComponent<SpriteRenderer>();
//spriteRenderer.sprite = Resources.Load("whiteSquare");
//spriteRenderer.color = new Color(0f, 0f, 0f, 0f.2f);
//panelRectTransform.anchorMin = new Vector2(1, 0);
//panelRectTransform.anchorMax = new Vector2(0, 1);
//panelRectTransform.pivot = new Vector2(0.5f, 0.5f);
// Set layer to backsplash?
}
public void Pop()
{
//backSplash.SetActive(gameObject.activeSelf == false);
gameObject.SetActive(gameObject.activeSelf == false);
}
}
}

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eabe165e5b1a70744a8073c1b5b541a7
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class DialogBox : MonoBehaviour
{
public List<GameObject> cloneObjects;
public void Pop()
{
gameObject.SetActive(gameObject.activeSelf == false);
}
public void RemoveCloneObjectsFromParent(Transform parent)
{
for (int i = 0; i < parent.childCount; i++)
{ Destroy(parent.transform.GetChild(i).gameObject); }
}
public GameObject AddCloneObjectToParent(Transform parent, int i = 0)
{
GameObject cloneObject = null;
if (cloneObjects != null && cloneObjects.Count > i)
{ cloneObject = Instantiate(cloneObjects[i], parent); }
return cloneObject;
}
}
}

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class SelectAnimationDialog : DialogBox
{
public void Initialize(Defs defs)
{
Transform contentWindow = transform.FindDeepChild("Content");
Reset();
for (int i = 0; i < defs.animationDefs.Count; i++)
{
AnimationDef animationDef = defs.animationDefs[i];
Transform _optionButton = AddCloneObjectToParent(contentWindow).transform;
_optionButton.Find("Text").GetComponent<Text>().text = animationDef.defName;
Button buttonComp = _optionButton.GetComponent<Button>();
buttonComp.onClick.AddListener(delegate { Pop(); ApplicationManager.Instance.LoadAnimation(animationDef); });
}
}
public void Reset()
{
Transform contentWindow = transform.FindDeepChild("Content");
RemoveCloneObjectsFromParent(contentWindow);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6db038d692d34c441b171c72c78e0066
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class SelectBodyDefTypesDialog : DialogBox
{
private Actor actor;
public void Start()
{
Initialize();
}
public void AddBodyDefType(InputField field)
{
Debug.Log("Attempting to add new body def type");
if (field?.text == null || field.text == "")
{ Debug.LogWarning("Input field is null"); return; }
if (Workspace.bodyDefTypes.Contains(field.text))
{ Debug.LogWarning("Body def type is null"); field.text = ""; return; }
Debug.Log("Added new body type def: " + field.text);
Workspace.bodyDefTypes.Add(field.text);
Initialize();
}
public void Initialize(Actor actor = null)
{
if (actor != null)
{ this.actor = actor; }
if (actor == null)
{ actor = this.actor; }
if (actor == null) return;
foreach (string bodyDefType in actor.bodyDefTypes)
{
if (Workspace.bodyDefTypes.Contains(bodyDefType) == false)
{ Workspace.bodyDefTypes.Add(bodyDefType); }
}
Transform contentWindow = transform.FindDeepChild("Content");
Reset();
for (int i = 0; i < Workspace.bodyDefTypes.Count; i++)
{
string bodyDefType = Workspace.bodyDefTypes[i];
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
_optionToggle.Find("Text").GetComponent<Text>().text = bodyDefType;
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
toggleComp.isOn = actor.bodyDefTypes.Contains(bodyDefType);
toggleComp.onValueChanged.AddListener(delegate {
if (toggleComp.isOn && actor.bodyDefTypes.Contains(bodyDefType) == false)
{ actor.bodyDefTypes.Add(bodyDefType); }
else if (toggleComp.isOn == false && actor.bodyDefTypes.Contains(bodyDefType))
{ actor.bodyDefTypes.Remove(bodyDefType); }
});
}
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
_optionField.Find("Placeholder").GetComponent<Text>().text = "Enter new body def type...";
InputField fieldComp = _optionField.GetComponent<InputField>();
fieldComp.onEndEdit.AddListener(delegate { AddBodyDefType(fieldComp); });
}
public void Reset()
{
Transform contentWindow = transform.FindDeepChild("Content");
RemoveCloneObjectsFromParent(contentWindow);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b66fb83b0bed5a0438f6fbe11f0c35e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class SelectBodyPartsDialog : DialogBox
{
private Actor actor;
public void Start()
{
Initialize();
}
public void AddBodyPart(InputField field)
{
Debug.Log("Attempting to add new body part");
if (field?.text == null || field.text == "")
{ Debug.LogWarning("Input field is null"); return; }
if (Workspace.bodyParts.Contains(field.text))
{ Debug.LogWarning("Body part is null"); field.text = ""; return; }
Debug.Log("Add new body part: " + field.text);
Workspace.bodyParts.Add(field.text);
Initialize();
}
public void Initialize(Actor actor = null)
{
if (actor != null)
{ this.actor = actor; }
if (actor == null)
{ actor = this.actor; }
if (actor == null) return;
foreach (string bodyPart in actor.requiredGenitals)
{
if (Workspace.bodyParts.Contains(bodyPart) == false)
{ Workspace.bodyParts.Add(bodyPart); }
}
Transform contentWindow = transform.FindDeepChild("Content");
Reset();
for (int i = 0; i < Workspace.bodyParts.Count; i++)
{
string bodyPart = Workspace.bodyParts[i];
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
_optionToggle.Find("Text").GetComponent<Text>().text = bodyPart;
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
toggleComp.isOn = actor.requiredGenitals.Contains(bodyPart);
toggleComp.onValueChanged.AddListener(delegate {
if (toggleComp.isOn && actor.requiredGenitals.Contains(bodyPart) == false)
{ actor.requiredGenitals.Add(bodyPart); }
else if (toggleComp.isOn == false && actor.requiredGenitals.Contains(bodyPart))
{ actor.requiredGenitals.Remove(bodyPart); }
});
}
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
_optionField.Find("Placeholder").GetComponent<Text>().text = "Enter new body part name...";
InputField fieldComp = _optionField.GetComponent<InputField>();
fieldComp.onEndEdit.AddListener(delegate { AddBodyPart(fieldComp); });
}
public void Reset()
{
Transform contentWindow = transform.FindDeepChild("Content");
RemoveCloneObjectsFromParent(contentWindow);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 459a1b2a918e12f468445853ea5821e0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class SelectDefNamesDialog : DialogBox
{
private Actor actor;
public void Start()
{
Initialize();
}
public void AddDefName(InputField field)
{
Debug.Log("Attempting to add new def name");
if (field?.text == null || field.text == "")
{ Debug.LogWarning("Input field is null"); return; }
if (Workspace.defNames.Contains(field.text))
{ Debug.LogWarning("Def name is null"); field.text = ""; return; }
Debug.Log("Added new def name: " + field.text);
Workspace.defNames.Add(field.text);
Initialize();
}
public void Initialize(Actor actor = null)
{
if (actor != null)
{ this.actor = actor; }
if (actor == null)
{ actor = this.actor; }
if (actor == null) return;
foreach (string defName in actor.defNames)
{
if (Workspace.defNames.Contains(defName) == false)
{ Workspace.defNames.Add(defName); }
}
Transform contentWindow = transform.FindDeepChild("Content");
Reset();
for (int i = 0; i < Workspace.defNames.Count; i++)
{
string defName = Workspace.defNames[i];
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
_optionToggle.Find("Text").GetComponent<Text>().text = defName;
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
toggleComp.isOn = actor.defNames.Contains(defName);
toggleComp.onValueChanged.AddListener(delegate {
if (toggleComp.isOn && actor.defNames.Contains(defName) == false)
{ actor.defNames.Add(defName); }
else if (toggleComp.isOn == false && actor.defNames.Contains(defName))
{ actor.defNames.Remove(defName); }
});
}
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
_optionField.Find("Placeholder").GetComponent<Text>().text = "Enter new def name...";
InputField fieldComp = _optionField.GetComponent<InputField>();
fieldComp.onEndEdit.AddListener(delegate { AddDefName(fieldComp); });
}
public void Reset()
{
Transform contentWindow = transform.FindDeepChild("Content");
RemoveCloneObjectsFromParent(contentWindow);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9842b9e0fd45d4643af5bed7ba2de307
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class SelectInteractionDefsDialog : DialogBox
{
public void Start()
{
Initialize();
}
public void AddBodyPart(InputField field)
{
if (field?.text == null || field.text == "")
{ return; }
if (Workspace.bodyParts.Contains(field.text))
{ field.text = ""; return; }
Workspace.interactionDefTypes.Add(field.text);
Initialize();
}
public void Initialize()
{
if (Workspace.animationDef == null) return;
foreach (string interactionDefType in Workspace.animationDef.interactionDefTypes)
{
if (Workspace.interactionDefTypes.Contains(interactionDefType) == false)
{ Workspace.interactionDefTypes.Add(interactionDefType); }
}
Transform contentWindow = transform.FindDeepChild("Content");
Reset();
for (int i = 0; i < Workspace.bodyParts.Count; i++)
{
string interactionDefType = Workspace.interactionDefTypes[i];
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
_optionToggle.Find("Text").GetComponent<Text>().text = interactionDefType;
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
toggleComp.isOn = Workspace.animationDef.interactionDefTypes.Contains(interactionDefType);
toggleComp.onValueChanged.AddListener(delegate {
if (toggleComp.isOn && Workspace.animationDef.interactionDefTypes.Contains(interactionDefType) == false)
{ Workspace.animationDef.interactionDefTypes.Add(interactionDefType); }
else if (toggleComp.isOn == false && Workspace.animationDef.interactionDefTypes.Contains(interactionDefType))
{ Workspace.animationDef.interactionDefTypes.Remove(interactionDefType); }
});
}
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
_optionField.Find("Placeholder").GetComponent<Text>().text = "Enter new interaction def type...";
InputField fieldComp = _optionField.GetComponent<InputField>();
fieldComp.onEndEdit.AddListener(delegate { AddBodyPart(fieldComp); });
}
public void Reset()
{
Transform contentWindow = transform.FindDeepChild("Content");
RemoveCloneObjectsFromParent(contentWindow);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: cace588a3682dc649b94355d8eee4a77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,76 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.UI;
namespace RimWorldAnimationStudio
{
public class SelectSexTypesDialog : DialogBox
{
public void Start()
{
Initialize();
}
public void AddSexType(InputField field)
{
if (field?.text == null || field.text == "")
{ return; }
if (Workspace.bodyParts.Contains(field.text))
{ field.text = ""; return; }
Workspace.sexTypes.Add(field.text);
Initialize();
}
public void Initialize()
{
if (Workspace.animationDef == null) return;
foreach (string sexType in Workspace.animationDef.sexTypes)
{
if (Workspace.sexTypes.Contains(sexType) == false)
{ Workspace.sexTypes.Add(sexType); }
}
Transform contentWindow = transform.FindDeepChild("Content");
Reset();
for (int i = 0; i < Workspace.bodyParts.Count; i++)
{
string sexType = Workspace.sexTypes[i];
Transform _optionToggle = AddCloneObjectToParent(contentWindow).transform;
_optionToggle.Find("Text").GetComponent<Text>().text = sexType;
Toggle toggleComp = _optionToggle.GetComponent<Toggle>();
toggleComp.isOn = Workspace.animationDef.sexTypes.Contains(sexType);
toggleComp.onValueChanged.AddListener(delegate {
if (toggleComp.isOn && Workspace.animationDef.sexTypes.Contains(sexType) == false)
{ Workspace.animationDef.sexTypes.Add(sexType); }
else if (toggleComp.isOn == false && Workspace.animationDef.sexTypes.Contains(sexType))
{ Workspace.animationDef.sexTypes.Remove(sexType); }
});
}
Transform _optionField = AddCloneObjectToParent(contentWindow, 1).transform;
_optionField.Find("Placeholder").GetComponent<Text>().text = "Enter new sex type...";
InputField fieldComp = _optionField.GetComponent<InputField>();
fieldComp.onEndEdit.AddListener(delegate { AddSexType(fieldComp); });
}
public void Reset()
{
Transform contentWindow = transform.FindDeepChild("Content");
RemoveCloneObjectsFromParent(contentWindow);
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1d4b7a5a5ddb7d744b726c3c13e2fc5e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -1,43 +0,0 @@
using System.Xml;
using System.Xml.Serialization;
public enum AltitudeLayer
{
[XmlEnum(Name = "Terrain")] Terrain,
[XmlEnum(Name = "TerrainScatter")] TerrainScatter,
[XmlEnum(Name = "Floor")] Floor,
[XmlEnum(Name = "Conduits")] Conduits,
[XmlEnum(Name = "FloorCoverings")] FloorCoverings,
[XmlEnum(Name = "FloorEmplacement")] FloorEmplacement,
[XmlEnum(Name = "Filth")] Filth,
[XmlEnum(Name = "Zone")] Zone,
[XmlEnum(Name = "SmallWire")] SmallWire,
[XmlEnum(Name = "LowPlant")] LowPlant,
[XmlEnum(Name = "MoteLow")] MoteLow,
[XmlEnum(Name = "Shadows")] Shadows,
[XmlEnum(Name = "DoorMoveable")] DoorMoveable,
[XmlEnum(Name = "Building")] Building,
[XmlEnum(Name = "BuildingOnTop")] BuildingOnTop,
[XmlEnum(Name = "MoteBelowThings")] MoteBelowThings,
[XmlEnum(Name = "Item")] Item,
[XmlEnum(Name = "ItemImportant")] ItemImportant,
[XmlEnum(Name = "LayingPawn")] LayingPawn,
[XmlEnum(Name = "PawnRope")] PawnRope,
[XmlEnum(Name = "Projectile")] Projectile,
[XmlEnum(Name = "Pawn")] Pawn,
[XmlEnum(Name = "PawnUnused")] PawnUnused,
[XmlEnum(Name = "PawnState")] PawnState,
[XmlEnum(Name = "Blueprint")] Blueprint,
[XmlEnum(Name = "MoteOverheadLow")] MoteOverheadLow,
[XmlEnum(Name = "MoteOverhead")] MoteOverhead,
[XmlEnum(Name = "Gas")] Gas,
[XmlEnum(Name = "Skyfaller")] Skyfaller,
[XmlEnum(Name = "Weather")] Weather,
[XmlEnum(Name = "LightingOverlay")] LightingOverlay,
[XmlEnum(Name = "VisEffects")] VisEffects,
[XmlEnum(Name = "FogOfWar")] FogOfWar,
[XmlEnum(Name = "WorldClipper")] WorldClipper,
[XmlEnum(Name = "MapDataOverlay")] MapDataOverlay,
[XmlEnum(Name = "MetaOverlays")] MetaOverlays,
}

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4b51dcdd346a0cc469b21a6ffe1592fc
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public static class IListExtensions
{
public static bool NullOrEmpty<T>(this IList<T> list)
{
return list == null || list.Any() == false;
}
public static bool NotNullOrEmpty<T>(this IList<T> list)
{
return NullOrEmpty<T>(list) == false;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a030b2589ac872442a0d1aea7f5b5e70
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,24 @@
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public static class TransformExtensions
{
public static Transform FindDeepChild(this Transform parent, string childName)
{
Queue<Transform> queue = new Queue<Transform>();
queue.Enqueue(parent);
while (queue.Count > 0)
{
var c = queue.Dequeue();
if (c.name == childName)
return c;
foreach (Transform t in c)
queue.Enqueue(t);
}
return null;
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 859d0be8594b5bc46aa3fb70f78149ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using UnityEngine;
namespace RimWorldAnimationStudio
{
public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static bool shuttingDown = false;
private static object threadLock = new object();
private static T instance;
public static T Instance
{
get
{
if (shuttingDown)
{
Debug.LogWarning("[Singleton] Instance '" + typeof(T) + "' already destroyed. Returning null.");
return null;
}
lock (threadLock)
{
if (instance == null)
{
instance = (T)FindObjectOfType(typeof(T));
if (instance == null)
{
var singletonObject = new GameObject();
instance = singletonObject.AddComponent<T>();
singletonObject.name = typeof(T).ToString() + " (Singleton)";
}
}
return instance;
}
}
}
private void Awake()
{
DontDestroyOnLoad(this.gameObject);
}
private void OnDestroy()
{
shuttingDown = true;
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c2afae193e74a1e4ba127241833aea0e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -7,41 +7,21 @@ using UnityEngine;
namespace RimWorldAnimationStudio
{
public class Workspace : MonoBehaviour
public class Workspace : Singleton<Workspace>
{
public AnimationDef animationDef;
public int stageID = 0;
public bool isDirty = false;
public static AnimationDef animationDef;
public static int stageID = 0;
public static bool isDirty = false;
public List<WorkspaceSnapShot> workspaceHistory = new List<WorkspaceSnapShot>();
public int maxHistoryDepth = 100;
public int historyIndex = 0;
public static List<string> defNames = new List<string>() { "Human" };
public static List<string> bodyParts = new List<string>() { "Penis", "Vagina", "Anus", "Breasts", "Mouth" };
public static List<string> bodyDefTypes = new List<string>() { "Human" };
public static List<string> sexTypes = new List<string>() { "None", "Vaginal", "Anal", "Oral", "Masturbation", "DoublePenetration", "Boobjob", "Handjob", "Footjob", "Fingering", "Scissoring", "MutualMasturbation", "Fisting", "MechImplant", "Rimming", "Fellatio", "Cunnilingus", "Sixtynine" };
public static List<string> interactionDefTypes = new List<string>();
public void TryToCloseApplication()
{
if (isDirty)
{
//exitDialog.Pop();
return;
}
CloseApplication();
}
public void CloseApplication()
{
Application.Quit();
}
public void GenerateLoadOptions(Defs defs)
{
for (int i = 0; i < defs.animationDefs.Count - 1; i++)
{
//Instantiate child button
//button.text
//buttoncallback = LoadADef(list[i]);
}
}
private static List<WorkspaceSnapShot> workspaceHistory = new List<WorkspaceSnapShot>();
private static int maxHistoryDepth = 100;
private static int historyIndex = 0;
public void TrackChanges()
{

View file

@ -8,9 +8,9 @@ using System.Xml.Serialization;
namespace RimWorldAnimationStudio
{
public class XmlUtility
public static class XmlUtility
{
public T ReadXML<T>(string path)
public static T ReadXML<T>(string path)
{
using (StreamReader stringReader = new StreamReader(path))
{
@ -20,17 +20,17 @@ namespace RimWorldAnimationStudio
}
}
public void WriteXML(AnimationDef animationDef, string path)
public static void WriteXML(Defs defs, string path)
{
if (animationDef == null || path == null || path == "")
if (defs == null || path == null || path == "")
{ return; }
XmlSerializer writer = new XmlSerializer(typeof(AnimationDef));
XmlSerializer writer = new XmlSerializer(typeof(Defs));
XmlSerializerNamespaces nameSpaces = new XmlSerializerNamespaces();
nameSpaces.Add("", "");
FileStream file = File.Create(path);
writer.Serialize(file, animationDef, nameSpaces);
writer.Serialize(file, defs, nameSpaces);
file.Close();
}
}