public static void AddOrSetDrumRopeLimits(long hookEntityId, float minRopeLength, float maxRopeLength) { RopeDrumLimits limits; if (!m_hookIdToRopeLimits.TryGetValue(hookEntityId, out limits)) { limits = new RopeDrumLimits(); m_hookIdToRopeLimits[hookEntityId] = limits; } limits.MinLength = minRopeLength; limits.MaxLength = maxRopeLength; long ropeId; if (m_hookIdToRopeId.TryGetValue(hookEntityId, out ropeId)) { var ropeData = m_ropeIdToRope[ropeId]; ApplyRopeLimits(ropeData, limits); } }
private static void ApplyRopeLimits(InternalRopeData ropeData, RopeDrumLimits limits = null) { if (limits == null) m_hookIdToRopeLimits.TryGetValue(ropeData.Public.HookEntityIdA, out limits); if (limits == null) m_hookIdToRopeLimits.TryGetValue(ropeData.Public.HookEntityIdB, out limits); if (limits != null) { Debug.Assert( m_hookIdToRopeLimits.ContainsKey(ropeData.Public.HookEntityIdA) ^ m_hookIdToRopeLimits.ContainsKey(ropeData.Public.HookEntityIdB), "Rope should only be connected to one drum with rope limits."); ropeData.Public.MinRopeLength = limits.MinLength; ropeData.Public.MaxRopeLength = limits.MaxLength; WindingData winding; float newLength; if (m_hookIdToWinding.TryGetValue(ropeData.Public.HookEntityIdA, out winding) && winding.IsUnlocked) newLength = limits.MaxLength; else if (m_hookIdToWinding.TryGetValue(ropeData.Public.HookEntityIdB, out winding) && winding.IsUnlocked) newLength = limits.MaxLength; else newLength = MathHelper.Clamp(ropeData.Public.CurrentRopeLength, limits.MinLength, limits.MaxLength); ropeData.Public.CurrentRopeLength = newLength; if (ropeData.ConstraintData != null) { // Would be nice if I could leave this up to the normal update by changing only target rope length. // But target rope length is limited to only certain delta in actual length per update. ropeData.ConstraintData.LinearLimit = newLength; ropeData.Constraint.RigidBodyA.Activate(); ropeData.Constraint.RigidBodyB.Activate(); } } ropeData.TargetRopeLength = ropeData.Public.CurrentRopeLength; }