private void AddAction(GameObject go, DFBlock blockData, DFBlock.RdbObject obj, int modelReference)
        {
            // Get model action record and description
            DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource;
            string description = blockData.RdbBlock.ModelReferenceList[modelReference].Description;

            // Check for known action types
            Vector3 actionRotation    = Vector3.zero;
            Vector3 actionTranslation = Vector3.zero;

            if ((action.Flags & (int)DFBlock.RdbActionFlags.Rotation) == (int)DFBlock.RdbActionFlags.Rotation)
            {
                actionRotation = (GetActionVector(ref action) / BlocksFile.RotationDivisor);
            }
            if ((action.Flags & (int)DFBlock.RdbActionFlags.Translation) == (int)DFBlock.RdbActionFlags.Translation)
            {
                actionTranslation = GetActionVector(ref action) * MeshReader.GlobalScale;
            }

            // A quick hack to fix special-case rotation issues.
            // Currently unknown if there is data indicating different rotation behaviour or if something else is happening.
            switch (description)
            {
            case "LID":
                actionRotation = new Vector3(0, 0, -90f);           // Coffin lids in Scourg barrow
                break;

            case "WHE":
                actionRotation = new Vector3(0, -360f, 0);          // Wheels in Direnni Tower
                break;
            }

            // Create action component
            DaggerfallAction c = go.AddComponent <DaggerfallAction>();

            c.ActionEnabled     = true;
            c.ModelDescription  = description;
            c.ActionRotation    = actionRotation;
            c.ActionTranslation = actionTranslation;
            c.ActionSoundID     = obj.Resources.ModelResource.SoundId;

            // Set duration in seconds
            // Not sure what timescale native value represents
            // Using 1/20 of native value in seconds
            c.ActionDuration = (float)action.Duration / 20f;
            c.ActionFlags    = action.Flags;

            // Create action links
            ActionLink link;

            link.gameObject = go;
            link.nextKey    = GetActionKey(groupIndex, action.NextObjectIndex);
            link.prevKey    = GetActionKey(groupIndex, action.PreviousObjectIndex);
            actionLinkDict.Add(GetActionKey(groupIndex, obj.Index), link);

            // Add sound
            AddActionAudioSource(go, (uint)c.ActionSoundID);

            return;
        }
示例#2
0
 /// <summary>
 /// Check is model has action record.
 /// </summary>
 private static bool HasAction(DFBlock.RdbObject obj)
 {
     DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource;
     if (action.Flags != 0)
     {
         return(true);
     }
     return(false);
 }
        private static bool HasAction(DFBlock blockData, DFBlock.RdbObject obj, int modelReference)
        {
            // Allow for known action types
            DFBlock.RdbActionResource action = obj.Resources.ModelResource.ActionResource;
            if (action.Flags != 0)
            {
                return(true);
            }

            return(false);
        }
示例#4
0
        /// <summary>
        /// Constructs a Vector3 from magnitude and direction in RDB action resource.
        /// </summary>
        private static Vector3 GetActionVector(ref DFBlock.RdbActionResource resource)
        {
            Vector3 vector    = Vector3.zero;
            float   magnitude = resource.Magnitude;

            switch (resource.Axis)
            {
            case DFBlock.RdbActionAxes.NegativeX:
                vector.x = -magnitude;
                break;

            case DFBlock.RdbActionAxes.NegativeY:
                vector.y = -magnitude;
                break;

            case DFBlock.RdbActionAxes.NegativeZ:
                vector.z = -magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveX:
                vector.x = magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveY:
                vector.y = magnitude;
                break;

            case DFBlock.RdbActionAxes.PositiveZ:
                vector.z = magnitude;
                break;

            default:
                magnitude = 0f;
                break;
            }

            return(vector);
        }
        /// <summary>
        /// Prepares an action record for use.
        /// </summary>
        /// <param name="action">DFBlock.RdbActionResource</param>
        /// <param name="modelNode">ModelNode</param>
        /// <param name="description">Description of model.</param>
        /// <param name="groupIndex">RDB group index.</param>
        /// <param name="modelIndex">RDB model index.</param>
        private void CreateModelAction(DFBlock.RdbActionResource action, ModelNode modelNode, string description, int groupIndex, int modelIndex)
        {
            // Store description in action node
            modelNode.Action.ModelDescription = description;

            // Handle special case actions. These are models like doors, which
            // do not have an action record, or the coffin lids in Scourg Barrow,
            // which do not use their action data at all.
            switch (description)
            {
            case "DOR":             // Door
            case "DDR":             // Double-door
                action.ActionType = DFBlock.RdbActionType.Rotation;
                action.Axis       = DFBlock.RdbActionAxes.PositiveY;
                action.Magnitude  = 512;
                action.Duration   = 60;
                break;

            case "WHE":             // Wheel
                action.Axis      = DFBlock.RdbActionAxes.PositiveY;
                action.Magnitude = 2000;
                action.Duration  = 67;
                break;

            case "LID":             // Coffin lid in Scourg Barrow
                action.Axis      = DFBlock.RdbActionAxes.NegativeZ;
                action.Magnitude = 512;
                action.Duration  = 80;
                break;

            default:                // Let everything else be handled as per action record
                break;
            }

            // Create action record for this model from Daggerfall's action record.
            // Only rotation and translation are supported at this time.
            switch (action.ActionType)
            {
            case DFBlock.RdbActionType.None:
                modelNode.Action.Enabled = false;
                return;

            case DFBlock.RdbActionType.Rotation:
                modelNode.Action.Rotation   = GetActionVector(ref action);
                modelNode.Action.Rotation.X =
                    -MathHelper.ToRadians(modelNode.Action.Rotation.X / rotationDivisor);
                modelNode.Action.Rotation.Y =
                    MathHelper.ToRadians(modelNode.Action.Rotation.Y / rotationDivisor);
                modelNode.Action.Rotation.Z =
                    MathHelper.ToRadians(modelNode.Action.Rotation.Z / rotationDivisor);
                break;

            case DFBlock.RdbActionType.Translation:
                modelNode.Action.Translation = GetActionVector(ref action);
                break;

            default:
                // Unsupported action type
                modelNode.Action.Enabled = false;
                return;
            }

            // Set duration.
            // Not really sure of the correct unit - definitely not milliseconds.
            // Using n/60ths of a second for now, which seems pretty close.
            modelNode.Action.Duration = (long)(1000f * (action.Duration / 60f));

            // Enable action
            modelNode.Action.Enabled = true;

            // Create action links
            ActionLink link;

            link.node    = modelNode;
            link.nextKey = GetActionKey(groupIndex, action.NextObjectIndex);
            link.prevKey = GetActionKey(groupIndex, action.PreviousObjectIndex);
            actionLinkDict.Add(GetActionKey(groupIndex, modelIndex), link);
        }