fix issue #4 "Incompatible animation may cause infinite loop [...]"
? function AnimationDef::postLoad now throws if any clip contained lacks mandatory curves ? function AnimationStage::initialize + parameter isGenitalAngleMandatory passes whether generally optional curve GenitalAngle is mandatory in this particular case + return value shows number of broken clips ? renamed to Initialize as per usual C# convention ? class BaseAnimationClip + function EmitMandatoryCurveEmptyError as fluent interface for checking mandatory curves ? function buildSimpleCurves + parameter isGenitalAngleMandatory as above + return value shows whether all mandatory curves for the clip have been filled ? renamed to Initialize as per usual C# convention
This commit is contained in:
parent
a9acb2bd62
commit
2cdffc37bc
|
@ -15,14 +15,17 @@ namespace Rimworld_Animations {
|
|||
public List<BaseAnimationClip> animationClips;
|
||||
public List<string> tags = new List<string>();
|
||||
|
||||
public void initialize() {
|
||||
foreach (BaseAnimationClip clip in animationClips) {
|
||||
clip.buildSimpleCurves();
|
||||
public int Initialize(List<bool> isGenitalAngleMandatory) {
|
||||
var brokenClips = 0;
|
||||
for (var i = 0; i < animationClips.Count; ++i) {
|
||||
var clip = animationClips[i];
|
||||
if (clip.BuildSimpleCurves(isGenitalAngleMandatory[i]))
|
||||
++brokenClips;
|
||||
//select playTimeTicks as longest playtime of all the animations
|
||||
if(clip.duration > playTimeTicks) {
|
||||
playTimeTicks = clip.duration;
|
||||
}
|
||||
if (clip.duration > playTimeTicks)
|
||||
playTimeTicks = clip.duration;
|
||||
}
|
||||
return brokenClips;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,9 +12,18 @@ namespace Rimworld_Animations {
|
|||
public Dictionary<int, string> SoundEffects = new Dictionary<int, string>();
|
||||
public List<ThingDef> types; //types of participants
|
||||
public int duration;
|
||||
public abstract void buildSimpleCurves();
|
||||
/** <returns>failure - if 'true', this clip should not be used</returns> */
|
||||
public abstract bool BuildSimpleCurves(bool isGenitalAngleMandatory = false);
|
||||
public string soundDef = null; //for playing sounds
|
||||
public int actor;
|
||||
public List<string> tags = new List<string>();
|
||||
|
||||
protected bool EmitMandatoryCurveEmptyError(SimpleCurve curve, string name) {
|
||||
if (curve.PointsCount <= 0) {
|
||||
Log.Error($"Mandatory curve '{name}' is empty in an animation clip!");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ namespace Rimworld_Animations {
|
|||
public SimpleCurve BodyOffsetZ = new SimpleCurve();
|
||||
public SimpleCurve HeadFacing = new SimpleCurve();
|
||||
public SimpleCurve BodyFacing = new SimpleCurve();
|
||||
|
||||
|
||||
public override void buildSimpleCurves() {
|
||||
|
||||
public override bool BuildSimpleCurves(bool isGenitalAngleMandatory) {
|
||||
|
||||
|
||||
int duration = 0;
|
||||
|
@ -109,7 +109,18 @@ namespace Rimworld_Animations {
|
|||
|
||||
}
|
||||
|
||||
// check whether all mandatory curves have been filled
|
||||
bool invalid = false;
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.BodyOffsetX, "BodyOffsetX");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.BodyOffsetZ, "BodyOffsetZ");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.BodyAngle, "BodyAngle");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.HeadAngle, "HeadAngle");
|
||||
if (isGenitalAngleMandatory)
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.GenitalAngle, "GenitalAngle");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.BodyFacing, "BodyFacing");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.HeadFacing, "HeadFacing");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.HeadBob, "HeadBob");
|
||||
return invalid;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Rimworld_Animations {
|
|||
public SimpleCurve Rotation = new SimpleCurve();
|
||||
|
||||
|
||||
public override void buildSimpleCurves() {
|
||||
public override bool BuildSimpleCurves(bool unused = false) {
|
||||
int duration = 0;
|
||||
//getting the length of the whole clip
|
||||
foreach (ThingKeyframe frame in keyframes)
|
||||
|
@ -69,6 +69,13 @@ namespace Rimworld_Animations {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// check whether all mandatory curves have been filled
|
||||
bool invalid = false;
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.PositionX, "PositionX");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.PositionZ, "PositionZ");
|
||||
invalid |= this.EmitMandatoryCurveEmptyError(this.Rotation, "Rotation");
|
||||
return invalid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,12 @@ namespace Rimworld_Animations {
|
|||
|
||||
public override void PostLoad() {
|
||||
base.PostLoad();
|
||||
// FIXME: I could not figure out how to map between controlGenitalAngle and PawnAnimationClip. This is brittle AF! -Zsar 2023-04-16
|
||||
var controlGenitalAngle = this.actors.ConvertAll(actor => actor.controlGenitalAngle);
|
||||
foreach(AnimationStage stage in animationStages) {
|
||||
stage.initialize();
|
||||
var brokenClips = stage.Initialize(controlGenitalAngle);
|
||||
if (brokenClips > 0)
|
||||
throw new Exception($"AnimationDef '{this.defName}', stage '{stage.stageName}' contained {brokenClips} broken Clips. The animation has been dropped.");
|
||||
animationTimeTicks += stage.playTimeTicks;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue