forked from Mirrors/openclonk
Add sanity check for animation length when using Anim_Linear as a position provider in PlayAnimation script function.
parent
221565952d
commit
103eb2528f
|
@ -42,7 +42,7 @@ namespace
|
|||
const StdMeshInstance::SerializableValueProvider::ID<C4ValueProviderAction> C4ValueProviderActionID("action");
|
||||
}
|
||||
|
||||
StdMeshInstance::ValueProvider* CreateValueProviderFromArray(C4Object* pForObj, C4ValueArray& Data)
|
||||
StdMeshInstance::ValueProvider* CreateValueProviderFromArray(C4Object* pForObj, C4ValueArray& Data, const StdMeshAnimation* pos_for_animation)
|
||||
{
|
||||
int32_t type = Data[0].getInt();
|
||||
switch (type)
|
||||
|
@ -50,9 +50,19 @@ StdMeshInstance::ValueProvider* CreateValueProviderFromArray(C4Object* pForObj,
|
|||
case C4AVP_Const:
|
||||
return new C4ValueProviderConst(itofix(Data[1].getInt(), 1000));
|
||||
case C4AVP_Linear:
|
||||
if (Data[4].getInt() == 0)
|
||||
{
|
||||
int32_t end = Data[3].getInt(), len = Data[4].getInt();
|
||||
if (len == 0)
|
||||
throw new C4AulExecError("Length cannot be zero");
|
||||
return new C4ValueProviderLinear(itofix(Data[1].getInt(), 1000), itofix(Data[2].getInt(), 1000), itofix(Data[3].getInt(), 1000), Data[4].getInt(), static_cast<C4AnimationEnding>(Data[5].getInt()));
|
||||
// Sanity check for linear animations that are too long and could cause excessive animation stacks
|
||||
if (pos_for_animation)
|
||||
{
|
||||
int32_t max_end = fixtoi(ftofix(pos_for_animation->Length), 1000);
|
||||
if (end < 0 || end > max_end)
|
||||
throw new C4AulExecError(FormatString("End (%d) not in range of animation '%s' (0-%d).", (int)end, pos_for_animation->Name.getData(), (int)max_end).getData());
|
||||
}
|
||||
return new C4ValueProviderLinear(itofix(Data[1].getInt(), 1000), itofix(Data[2].getInt(), 1000), itofix(end, 1000), len, static_cast<C4AnimationEnding>(Data[5].getInt()));
|
||||
}
|
||||
case C4AVP_X:
|
||||
if (!pForObj) return NULL;
|
||||
if (Data[4].getInt() == 0)
|
||||
|
|
|
@ -349,6 +349,6 @@ private:
|
|||
C4Real Scale;
|
||||
};
|
||||
|
||||
StdMeshInstance::ValueProvider* CreateValueProviderFromArray(C4Object* pForObj, C4ValueArray& Data);
|
||||
StdMeshInstance::ValueProvider* CreateValueProviderFromArray(C4Object* pForObj, C4ValueArray& Data, const StdMeshAnimation* pos_for_animation = NULL);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1835,7 +1835,10 @@ static Nillable<int> FnPlayAnimation(C4Object *Obj, C4String *szAnimation, int i
|
|||
if (!s_node || s_node->GetSlot() != iSlot) return C4Void();
|
||||
}
|
||||
|
||||
StdMeshInstance::ValueProvider* p_provider = CreateValueProviderFromArray(Obj, *PositionProvider);
|
||||
const StdMeshAnimation* animation = Instance->GetMesh().GetSkeleton().GetAnimationByName(szAnimation->GetData());
|
||||
if (!animation) return C4Void();
|
||||
|
||||
StdMeshInstance::ValueProvider* p_provider = CreateValueProviderFromArray(Obj, *PositionProvider, animation);
|
||||
StdMeshInstance::ValueProvider* w_provider = CreateValueProviderFromArray(Obj, *WeightProvider);
|
||||
if (!p_provider || !w_provider)
|
||||
{
|
||||
|
@ -1844,7 +1847,7 @@ static Nillable<int> FnPlayAnimation(C4Object *Obj, C4String *szAnimation, int i
|
|||
return C4Void();
|
||||
}
|
||||
|
||||
StdMeshInstance::AnimationNode* n_node = Instance->PlayAnimation(szAnimation->GetData(), iSlot, s_node, p_provider, w_provider);
|
||||
StdMeshInstance::AnimationNode* n_node = Instance->PlayAnimation(*animation, iSlot, s_node, p_provider, w_provider);
|
||||
if (!n_node) return C4Void();
|
||||
|
||||
return n_node->GetNumber();
|
||||
|
|
Loading…
Reference in New Issue