示例#1
0
    public void AddTarget(float x, float y, float beatTime, float beatLength = 1, TargetVelocity velocity = TargetVelocity.Standard, TargetHandType handType = TargetHandType.Either, TargetBehavior behavior = TargetBehavior.Standard)
    {
        // Add to timeline
        var timelineClone = Instantiate(timelineNotePrefab, timelineNotes);

        timelineClone.transform.localPosition = new Vector3(beatTime, 0, 0);

        // Add to grid
        var gridClone = Instantiate(gridNotePrefab, gridNotes);

        gridClone.transform.localPosition = new Vector3(x, y, beatTime);

        gridClone.timelineTarget     = timelineClone;
        timelineClone.timelineTarget = timelineClone;
        gridClone.gridTarget         = gridClone;
        timelineClone.gridTarget     = gridClone;

        gridClone.SetHandType(handType);
        gridClone.SetBehavior(behavior);
        gridClone.SetBeatLength(beatLength);
        gridClone.SetVelocity(velocity);

        notes.Add(gridClone);

        UpdateTrail();
    }
示例#2
0
    private void CalculateTargetVelocity()
    {
        TargetVelocity = MoveInput;
        TargetVelocity = TargetVelocity.Rotated(Agent.Body._rotation.y, Agent.Body._rotation.x);

        TargetVelocity       *= Speed;
        TargetVelocityReached = false;
    }
示例#3
0
 public TargetData(Target target)
 {
     x          = target.gridTargetIcon.transform.localPosition.x;
     y          = target.gridTargetIcon.transform.localPosition.y;
     beatTime   = target.gridTargetIcon.transform.localPosition.z;
     beatLength = target.beatLength;
     velocity   = target.velocity;
     handType   = target.handType;
     behavior   = target.behavior;
 }
示例#4
0
        public TargetData(Cue cue, float offset)
        {
            Vector2 pos = NotePosCalc.PitchToPos(cue);

            x          = pos.x;
            y          = pos.y;
            beatTime   = (cue.tick - offset) / 480f;
            beatLength = cue.tickLength;
            velocity   = cue.velocity;
            handType   = cue.handType;
            behavior   = cue.behavior;
        }
        protected override YAMLMappingNode ExportYAMLRoot(IExportContainer container)
        {
            YAMLMappingNode node = base.ExportYAMLRoot(container);

            node.Add(ConnectedBodyName, ConnectedBody.ExportYAML(container));
            node.Add(AnchorName, Anchor.ExportYAML(container));
            node.Add(AxisName, Axis.ExportYAML(container));
            node.Add(AutoConfigureConnectedAnchorName, AutoConfigureConnectedAnchor);
            node.Add(ConnectedAnchorName, ConnectedAnchor.ExportYAML(container));

            node.AddSerializedVersion(GetSerializedVersion(container.ExportVersion));
            node.Add(SecondaryAxisName, SecondaryAxis.ExportYAML(container));
            node.Add(XMotionName, (int)XMotion);
            node.Add(YMotionName, (int)YMotion);
            node.Add(ZMotionName, (int)ZMotion);
            node.Add(AngularXMotionName, (int)AngularXMotion);
            node.Add(AngularYMotionName, (int)AngularYMotion);
            node.Add(AngularZMotionName, (int)AngularZMotion);
            node.Add(LinearLimitSpringName, LinearLimitSpring.ExportYAML(container));
            node.Add(LinearLimitName, LinearLimit.ExportYAML(container));
            node.Add(AngularXLimitSpringName, AngularXLimitSpring.ExportYAML(container));
            node.Add(LowAngularXLimitName, LowAngularXLimit.ExportYAML(container));
            node.Add(HighAngularXLimitName, HighAngularXLimit.ExportYAML(container));
            node.Add(AngularYZLimitSpringName, AngularYZLimitSpring.ExportYAML(container));
            node.Add(AngularYLimitName, AngularYLimit.ExportYAML(container));
            node.Add(AngularZLimitName, AngularZLimit.ExportYAML(container));
            node.Add(TargetPositionName, TargetPosition.ExportYAML(container));
            node.Add(TargetVelocityName, TargetVelocity.ExportYAML(container));
            node.Add(XDriveName, XDrive.ExportYAML(container));
            node.Add(YDriveName, YDrive.ExportYAML(container));
            node.Add(ZDriveName, ZDrive.ExportYAML(container));
            node.Add(TargetRotationName, TargetRotation.ExportYAML(container));
            node.Add(TargetAngularVelocityName, TargetAngularVelocity.ExportYAML(container));
            node.Add(RotationDriveModeName, (int)RotationDriveMode);
            node.Add(AngularXDriveName, AngularXDrive.ExportYAML(container));
            node.Add(AngularYZDriveName, AngularYZDrive.ExportYAML(container));
            node.Add(SlerpDriveName, SlerpDrive.ExportYAML(container));
            node.Add(ProjectionModeName, (int)ProjectionMode);
            node.Add(ProjectionDistanceName, ProjectionDistance);
            node.Add(ProjectionAngleName, ProjectionAngle);
            node.Add(ConfiguredInWorldSpaceName, ConfiguredInWorldSpace);
            node.Add(SwapBodiesName, SwapBodies);

            node.Add(BreakForceName, BreakForce);
            node.Add(BreakTorqueName, BreakTorque);
            node.Add(EnableCollisionName, EnableCollision);
            node.Add(EnablePreprocessingName, EnablePreprocessing);
            node.Add(MassScaleName, MassScale);
            node.Add(ConnectedMassScaleName, ConnectedMassScale);
            return(node);
        }
        public void Update(ComponentizedEntity entity, IGameContext gameContext, IUpdateContext updateContext)
        {
            if (!Enabled)
            {
                return;
            }

            if (_jitterWorld != _physicsEngine.GetInternalPhysicsWorld())
            {
                // TODO: Deregister rigid bodies from old world.
                if (_jitterWorld != null && _physicsControllerConstraint != null)
                {
                    _jitterWorld.RemoveConstraint(_physicsControllerConstraint);
                    _physicsControllerConstraint = null;
                }
                _jitterWorld = _physicsEngine.GetInternalPhysicsWorld();
            }

            if (_physicalComponent.RigidBodies.Length > 0 && _physicalComponent.RigidBodies[0] != _rigidBody)
            {
                if (_physicsControllerConstraint != null)
                {
                    _jitterWorld.RemoveConstraint(_physicsControllerConstraint);
                    _physicsControllerConstraint = null;
                }
            }

            if (_physicalComponent.RigidBodies.Length > 0)
            {
                if (_physicsControllerConstraint == null)
                {
                    _physicsControllerConstraint = new PhysicsControllerConstraint(
                        _jitterWorld,
                        _physicalComponent.RigidBodies[0]);
                    _jitterWorld.AddConstraint(_physicsControllerConstraint);
                }

                _physicsControllerConstraint.TargetVelocity = TargetVelocity.ToJitterVector();
                _physicsControllerConstraint.TryJump        = TryJump;
                _physicsControllerConstraint.JumpVelocity   = JumpVelocity;
                _physicsControllerConstraint.Stiffness      = Stiffness;

                if (TargetVelocity.LengthSquared() > 0f)
                {
                    // Wake up the rigid body.
                    _physicalComponent.RigidBodies[0].IsActive = true;
                }
            }
        }
示例#7
0
        private void SetHitsoundAction(TargetVelocity velocity)
        {
            targetSetHitsoundIntents = new List <TargetSetHitsoundIntent>();
            timeline.selectedNotes.ForEach(target => {
                var intent = new TargetSetHitsoundIntent();

                intent.target           = target.data;
                intent.startingVelocity = target.data.velocity;
                intent.newVelocity      = velocity;

                targetSetHitsoundIntents.Add(intent);
            });

            timeline.SetTargetHitsounds(targetSetHitsoundIntents);
        }
示例#8
0
        public static void CalculateChainNotes(TargetData data)
        {
            if (data.behavior != TargetBehavior.NR_Pathbuilder)
            {
                return;
            }

            if (data.pathBuilderData.createdNotes)
            {
                data.pathBuilderData.generatedNotes.ForEach(t => {
                    timeline.DeleteTargetFromAction(t);
                });
                data.pathBuilderData.createdNotes = false;
            }

            data.pathBuilderData.generatedNotes = new List <TargetData>();

            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            /////////                                            WARNING!                                                      /////////
            /////////       Chainging this calculation breaks backwards compatibility with saves of older NotReaper versions!  /////////
            /////////                    Make sure to update NRCueData.Version, and handle an upgrade path!                    /////////
            ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

            //Generate first note at the start
            TargetData firstData = new TargetData();

            firstData.behavior = data.pathBuilderData.behavior;
            firstData.velocity = data.pathBuilderData.velocity;
            firstData.handType = data.pathBuilderData.handType;
            firstData.beatTime = data.beatTime;
            firstData.position = data.position;
            data.pathBuilderData.generatedNotes.Add(firstData);

            //We increment as if all these values were for 1/4 notes over 4 beats, makes the ui much better
            float quarterIncrConvert = (4.0f / data.pathBuilderData.interval) * (480.0f * 4.0f / data.beatLength);

            //Generate new notes
            Vector2 currentPos   = data.position;
            Vector2 currentDir   = new Vector2(Mathf.Sin(data.pathBuilderData.initialAngle * Mathf.Deg2Rad), Mathf.Cos(data.pathBuilderData.initialAngle * Mathf.Deg2Rad));
            float   currentAngle = (data.pathBuilderData.angle / 4) * quarterIncrConvert;
            float   currentStep  = data.pathBuilderData.stepDistance * quarterIncrConvert;

            TargetBehavior generatedBehavior = data.pathBuilderData.behavior;

            if (generatedBehavior == TargetBehavior.ChainStart)
            {
                generatedBehavior = TargetBehavior.Chain;
            }

            TargetVelocity generatedVelocity = data.pathBuilderData.velocity;

            if (generatedVelocity == TargetVelocity.ChainStart)
            {
                generatedVelocity = TargetVelocity.Chain;
            }

            for (int i = 1; i <= (data.beatLength / 480) * (data.pathBuilderData.interval / 4.0f); ++i)
            {
                currentPos += currentDir * currentStep;
                currentDir  = currentDir.Rotate(currentAngle);

                currentAngle += (data.pathBuilderData.angleIncrement / 4) * quarterIncrConvert;
                currentStep  += data.pathBuilderData.stepIncrement * quarterIncrConvert;

                TargetData newData = new TargetData();
                newData.behavior = generatedBehavior;
                newData.velocity = generatedVelocity;
                newData.handType = data.pathBuilderData.handType;
                newData.beatTime = data.beatTime + i * (4.0f / data.pathBuilderData.interval);
                newData.position = currentPos;
                data.pathBuilderData.generatedNotes.Add(newData);
            }

            data.pathBuilderData.OnFinishRecalculate();
        }
示例#9
0
 public void SetVelocity(TargetVelocity velocity)
 {
     gridTarget.velocity = velocity;
 }
示例#10
0
        private void UpdateAutoPilot(float deltaTime)
        {
            if (controlledSub == null)
            {
                return;
            }
            if (posToMaintain != null)
            {
                Vector2 steeringVel = GetSteeringVelocity((Vector2)posToMaintain, 10.0f);
                TargetVelocity      = Vector2.Lerp(TargetVelocity, steeringVel, AutoPilotSteeringLerp);
                showIceSpireWarning = false;
                return;
            }

            autopilotRayCastTimer         -= deltaTime;
            autopilotRecalculatePathTimer -= deltaTime;
            if (autopilotRecalculatePathTimer <= 0.0f)
            {
                //periodically recalculate the path in case the sub ends up to a position
                //where it can't keep traversing the initially calculated path
                UpdatePath();
                autopilotRecalculatePathTimer = RecalculatePathInterval;
            }

            if (steeringPath == null)
            {
                showIceSpireWarning = false;
                return;
            }
            steeringPath.CheckProgress(ConvertUnits.ToSimUnits(controlledSub.WorldPosition), 10.0f);

            connectedSubUpdateTimer -= deltaTime;
            if (connectedSubUpdateTimer <= 0.0f)
            {
                connectedSubs.Clear();
                connectedSubs           = controlledSub?.GetConnectedSubs();
                connectedSubUpdateTimer = ConnectedSubUpdateInterval;
            }

            if (autopilotRayCastTimer <= 0.0f && steeringPath.NextNode != null)
            {
                Vector2 diff = ConvertUnits.ToSimUnits(steeringPath.NextNode.Position - controlledSub.WorldPosition);

                //if the node is close enough, check if it's visible
                float lengthSqr = diff.LengthSquared();
                if (lengthSqr > 0.001f && lengthSqr < AutopilotMinDistToPathNode * AutopilotMinDistToPathNode)
                {
                    diff = Vector2.Normalize(diff);

                    //check if the next waypoint is visible from all corners of the sub
                    //(i.e. if we can navigate directly towards it or if there's obstacles in the way)
                    bool nextVisible = true;
                    for (int x = -1; x < 2; x += 2)
                    {
                        for (int y = -1; y < 2; y += 2)
                        {
                            Vector2 cornerPos =
                                new Vector2(controlledSub.Borders.Width * x, controlledSub.Borders.Height * y) / 2.0f;

                            cornerPos = ConvertUnits.ToSimUnits(cornerPos * 1.1f + controlledSub.WorldPosition);

                            float dist = Vector2.Distance(cornerPos, steeringPath.NextNode.SimPosition);

                            if (Submarine.PickBody(cornerPos, cornerPos + diff * dist, null, Physics.CollisionLevel) == null)
                            {
                                continue;
                            }

                            nextVisible = false;
                            x           = 2;
                            y           = 2;
                        }
                    }

                    if (nextVisible)
                    {
                        steeringPath.SkipToNextNode();
                    }
                }

                autopilotRayCastTimer = AutopilotRayCastInterval;
            }

            Vector2 newVelocity = Vector2.Zero;

            if (steeringPath.CurrentNode != null)
            {
                newVelocity = GetSteeringVelocity(steeringPath.CurrentNode.WorldPosition, 2.0f);
            }

            Vector2 avoidDist = new Vector2(
                Math.Max(1000.0f * Math.Abs(controlledSub.Velocity.X), controlledSub.Borders.Width * 0.75f),
                Math.Max(1000.0f * Math.Abs(controlledSub.Velocity.Y), controlledSub.Borders.Height * 0.75f));

            float avoidRadius             = avoidDist.Length();
            float damagingWallAvoidRadius = MathHelper.Clamp(avoidRadius * 1.5f, 5000.0f, 10000.0f);

            Vector2 newAvoidStrength = Vector2.Zero;

            debugDrawObstacles.Clear();

            //steer away from nearby walls
            showIceSpireWarning = false;
            var closeCells = Level.Loaded.GetCells(controlledSub.WorldPosition, 4);

            foreach (VoronoiCell cell in closeCells)
            {
                if (cell.DoesDamage)
                {
                    foreach (GraphEdge edge in cell.Edges)
                    {
                        Vector2 closestPoint = MathUtils.GetClosestPointOnLineSegment(edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, controlledSub.WorldPosition);
                        Vector2 diff         = closestPoint - controlledSub.WorldPosition;
                        float   dist         = diff.Length() - Math.Max(controlledSub.Borders.Width, controlledSub.Borders.Height) / 2;
                        if (dist > damagingWallAvoidRadius)
                        {
                            continue;
                        }

                        Vector2 normalizedDiff = Vector2.Normalize(diff);
                        float   dot            = Vector2.Dot(normalizedDiff, controlledSub.Velocity);

                        float   avoidStrength = MathHelper.Clamp(MathHelper.Lerp(1.0f, 0.0f, dist / damagingWallAvoidRadius - dot), 0.0f, 1.0f);
                        Vector2 avoid         = -normalizedDiff * avoidStrength;
                        newAvoidStrength += avoid;
                        debugDrawObstacles.Add(new ObstacleDebugInfo(edge, edge.Center, 1.0f, avoid, cell.Translation));

                        if (dot > 0.0f)
                        {
                            showIceSpireWarning = true;
                        }
                    }
                    continue;
                }

                foreach (GraphEdge edge in cell.Edges)
                {
                    if (MathUtils.GetLineIntersection(edge.Point1 + cell.Translation, edge.Point2 + cell.Translation, controlledSub.WorldPosition, cell.Center, out Vector2 intersection))
                    {
                        Vector2 diff = controlledSub.WorldPosition - intersection;
                        //far enough -> ignore
                        if (Math.Abs(diff.X) > avoidDist.X && Math.Abs(diff.Y) > avoidDist.Y)
                        {
                            debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, 0.0f, Vector2.Zero, Vector2.Zero));
                            continue;
                        }
                        if (diff.LengthSquared() < 1.0f)
                        {
                            diff = Vector2.UnitY;
                        }

                        Vector2 normalizedDiff = Vector2.Normalize(diff);
                        float   dot            = controlledSub.Velocity == Vector2.Zero ?
                                                 0.0f : Vector2.Dot(controlledSub.Velocity, -normalizedDiff);

                        //not heading towards the wall -> ignore
                        if (dot < 1.0)
                        {
                            debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, dot, Vector2.Zero, cell.Translation));
                            continue;
                        }

                        Vector2 change = (normalizedDiff * Math.Max((avoidRadius - diff.Length()), 0.0f)) / avoidRadius;
                        if (change.LengthSquared() < 0.001f)
                        {
                            continue;
                        }
                        newAvoidStrength += change * (dot - 1.0f);
                        debugDrawObstacles.Add(new ObstacleDebugInfo(edge, intersection, dot - 1.0f, change * (dot - 1.0f), cell.Translation));
                    }
                }
            }

            avoidStrength  = Vector2.Lerp(avoidStrength, newAvoidStrength, deltaTime * 10.0f);
            TargetVelocity = Vector2.Lerp(TargetVelocity, newVelocity + avoidStrength * 100.0f, AutoPilotSteeringLerp);

            //steer away from other subs
            foreach (Submarine sub in Submarine.Loaded)
            {
                if (sub == controlledSub || connectedSubs.Contains(sub))
                {
                    continue;
                }
                Point   sizeSum          = controlledSub.Borders.Size + sub.Borders.Size;
                Vector2 minDist          = sizeSum.ToVector2() / 2;
                Vector2 diff             = controlledSub.WorldPosition - sub.WorldPosition;
                float   xDist            = Math.Abs(diff.X);
                float   yDist            = Math.Abs(diff.Y);
                Vector2 maxAvoidDistance = minDist * 2;
                if (xDist > maxAvoidDistance.X || yDist > maxAvoidDistance.Y)
                {
                    //far enough -> ignore
                    continue;
                }
                float dot = controlledSub.Velocity == Vector2.Zero ? 0.0f : Vector2.Dot(Vector2.Normalize(controlledSub.Velocity), -diff);
                if (dot < 0.0f)
                {
                    //heading away -> ignore
                    continue;
                }
                float distanceFactor = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(maxAvoidDistance.X + maxAvoidDistance.Y, minDist.X + minDist.Y, xDist + yDist));
                float velocityFactor = MathHelper.Lerp(0, 1, MathUtils.InverseLerp(0, 3, controlledSub.Velocity.Length()));
                TargetVelocity += 100 * Vector2.Normalize(diff) * distanceFactor * velocityFactor;
            }

            //clamp velocity magnitude to 100.0f (Is this required? The X and Y components are clamped in the property setter)
            float velMagnitude = TargetVelocity.Length();

            if (velMagnitude > 100.0f)
            {
                TargetVelocity *= 100.0f / velMagnitude;
            }

#if CLIENT
            HintManager.OnAutoPilotPathUpdated(this);
#endif
        }
示例#11
0
        public override void Update(float deltaTime, Camera cam)
        {
            if (!searchedConnectedDockingPort)
            {
                FindConnectedDockingPort();
            }
            networkUpdateTimer -= deltaTime;
            if (unsentChanges)
            {
                if (networkUpdateTimer <= 0.0f)
                {
#if CLIENT
                    if (GameMain.Client != null)
                    {
                        item.CreateClientEvent(this);
                        correctionTimer = CorrectionDelay;
                    }
                    else
#endif
#if SERVER
                    if (GameMain.Server != null)
                    {
                        item.CreateServerEvent(this);
                    }
#endif

                    networkUpdateTimer = 0.1f;
                    unsentChanges      = false;
                }
            }

            controlledSub = item.Submarine;
            var sonar = item.GetComponent <Sonar>();
            if (sonar != null && sonar.UseTransducers)
            {
                controlledSub = sonar.ConnectedTransducers.Any() ? sonar.ConnectedTransducers.First().Item.Submarine : null;
            }

            currPowerConsumption = powerConsumption;

            if (Voltage < MinVoltage)
            {
                return;
            }

            if (user != null && user.Removed)
            {
                user = null;
            }

            ApplyStatusEffects(ActionType.OnActive, deltaTime, null);

            float userSkill = 0.0f;
            if (user != null && controlledSub != null &&
                (user.SelectedConstruction == item || item.linkedTo.Contains(user.SelectedConstruction)))
            {
                userSkill = user.GetSkillLevel("helm") / 100.0f;
            }

            if (AutoPilot)
            {
                UpdateAutoPilot(deltaTime);
                TargetVelocity = TargetVelocity.ClampLength(MathHelper.Lerp(AutoPilotMaxSpeed, AIPilotMaxSpeed, userSkill) * 100.0f);
            }
            else
            {
                showIceSpireWarning = false;
                if (user != null && user.Info != null &&
                    user.SelectedConstruction == item &&
                    controlledSub != null && controlledSub.Velocity.LengthSquared() > 0.01f)
                {
                    IncreaseSkillLevel(user, deltaTime);
                }

                Vector2 velocityDiff = steeringInput - targetVelocity;
                if (velocityDiff != Vector2.Zero)
                {
                    if (steeringAdjustSpeed >= 0.99f)
                    {
                        TargetVelocity = steeringInput;
                    }
                    else
                    {
                        float steeringChange = 1.0f / (1.0f - steeringAdjustSpeed);
                        steeringChange *= steeringChange * 10.0f;

                        TargetVelocity += Vector2.Normalize(velocityDiff) *
                                          Math.Min(steeringChange * deltaTime, velocityDiff.Length());
                    }
                }
            }

            float velX = targetVelocity.X;
            if (controlledSub != null && controlledSub.FlippedX)
            {
                velX *= -1;
            }
            item.SendSignal(new Signal(velX.ToString(CultureInfo.InvariantCulture), sender: user), "velocity_x_out");

            float velY = MathHelper.Lerp((neutralBallastLevel * 100 - 50) * 2, -100 * Math.Sign(targetVelocity.Y), Math.Abs(targetVelocity.Y) / 100.0f);
            item.SendSignal(new Signal(velY.ToString(CultureInfo.InvariantCulture), sender: user), "velocity_y_out");
        }
示例#12
0
        public override void DoAction(Timeline timeline)
        {
            oldBehavior = new List <TargetBehavior>();

            affectedTargets.ForEach(targetData => {
                TargetVelocity velocity = TargetVelocity.None;

                if (newBehavior == TargetBehavior.ChainStart)
                {
                    velocity = TargetVelocity.ChainStart;
                }
                else if (newBehavior == TargetBehavior.Chain)
                {
                    velocity = TargetVelocity.Chain;
                }
                else if (newBehavior == TargetBehavior.Melee)
                {
                    velocity = TargetVelocity.Melee;
                }
                else if (newBehavior == TargetBehavior.Mine)
                {
                    velocity = TargetVelocity.Mine;
                }
                else if (newBehavior == TargetBehavior.Standard ||
                         newBehavior == TargetBehavior.Hold ||
                         newBehavior == TargetBehavior.Horizontal ||
                         newBehavior == TargetBehavior.Vertical)
                {
                    velocity = TargetVelocity.Standard;
                }

                //Path notes and regular notes both use the same beat length
                oldBeatLength.Add(targetData.beatLength);

                if (targetData.behavior == TargetBehavior.NR_Pathbuilder)
                {
                    oldBehavior.Add(targetData.pathBuilderData.behavior);
                    oldHandTypes.Add(targetData.pathBuilderData.handType);
                    oldVelocities.Add(targetData.pathBuilderData.velocity);

                    targetData.pathBuilderData.behavior = newBehavior;
                    if (velocity != TargetVelocity.None)
                    {
                        targetData.pathBuilderData.velocity = velocity;
                    }

                    //Fix hand type when going to melee
                    if (newBehavior == TargetBehavior.Melee)
                    {
                        targetData.pathBuilderData.handType = TargetHandType.Either;
                    }

                    //Fixup hand type when coming from melee
                    if (oldBehavior.Last() == TargetBehavior.Melee)
                    {
                        targetData.pathBuilderData.handType = targetData.handType;
                    }

                    ChainBuilder.ChainBuilder.GenerateChainNotes(targetData);
                }
                else
                {
                    oldBehavior.Add(targetData.behavior);
                    oldHandTypes.Add(targetData.handType);
                    oldVelocities.Add(targetData.velocity);

                    targetData.behavior = newBehavior;
                    if (velocity != TargetVelocity.None)
                    {
                        targetData.velocity = velocity;
                    }

                    //Fix hand type when going to melee
                    if (newBehavior == TargetBehavior.Melee)
                    {
                        targetData.handType = TargetHandType.Either;
                    }

                    //Fixup hand type when coming from melee
                    if (oldBehavior.Last() == TargetBehavior.Melee)
                    {
                        targetData.handType = TargetHandType.Left;
                    }

                    if (TargetData.BehaviorSupportsBeatLength(newBehavior) && targetData.beatLength < Constants.QuarterNoteDuration)
                    {
                        targetData.beatLength = Constants.QuarterNoteDuration;
                    }
                }
            });
        }
示例#13
0
 public void SetVelocity(TargetVelocity velocity)
 {
     selectedVelocity = velocity;
 }
示例#14
0
    public void AddTarget(float x, float y, float beatTime, float beatLength = 0.25f, TargetVelocity velocity = TargetVelocity.Standard, TargetHandType handType = TargetHandType.Either, TargetBehavior behavior = TargetBehavior.Standard, bool userAdded = false)
    {
        // Add to timeline
        var timelineClone = Instantiate(timelineNotePrefab, timelineNotes);

        timelineClone.transform.localPosition = new Vector3(beatTime, 0, 0);

        // Add to grid
        var gridClone = Instantiate(gridNotePrefab, gridNotes);

        gridClone.GetComponentInChildren <HoldController>().length.text = "" + beatLength;
        gridClone.transform.localPosition = new Vector3(x, y, beatTime);

        gridClone.timelineTarget     = timelineClone;
        timelineClone.timelineTarget = timelineClone;
        gridClone.gridTarget         = gridClone;
        timelineClone.gridTarget     = gridClone;

        //set velocity
        if (userAdded)
        {
            switch (CurrentSound)
            {
            case OptionsMenu.DropdownToVelocity.Standard:
                gridClone.velocity = TargetVelocity.Standard;
                break;

            case OptionsMenu.DropdownToVelocity.Snare:
                gridClone.velocity = TargetVelocity.Snare;
                break;

            case OptionsMenu.DropdownToVelocity.Percussion:
                gridClone.velocity = TargetVelocity.Percussion;
                break;

            case OptionsMenu.DropdownToVelocity.ChainStart:
                gridClone.velocity = TargetVelocity.ChainStart;
                break;

            case OptionsMenu.DropdownToVelocity.Chain:
                gridClone.velocity = TargetVelocity.Chain;
                break;

            case OptionsMenu.DropdownToVelocity.Melee:
                gridClone.velocity = TargetVelocity.Melee;
                break;

            default:
                gridClone.velocity = velocity;
                break;
            }
        }
        else
        {
            gridClone.SetVelocity(velocity);
        }



        gridClone.SetHandType(handType);
        gridClone.SetBehavior(behavior);

        if (gridClone.behavior == TargetBehavior.Hold)
        {
            gridClone.SetBeatLength(beatLength);
        }
        else
        {
            gridClone.SetBeatLength(0.25f);
        }


        notes.Add(gridClone);
        notesTimeline.Add(timelineClone);

        orderedNotes = notes.OrderBy(v => v.transform.position.z).ToList();

        UpdateTrail();
        UpdateChainConnectors();
    }
示例#15
0
        public override void Update(float deltaTime, Camera cam)
        {
            if (!searchedConnectedDockingPort)
            {
                FindConnectedDockingPort();
            }
            networkUpdateTimer -= deltaTime;
            if (unsentChanges)
            {
                if (networkUpdateTimer <= 0.0f)
                {
#if CLIENT
                    if (GameMain.Client != null)
                    {
                        item.CreateClientEvent(this);
                        correctionTimer = CorrectionDelay;
                    }
                    else
#endif
#if SERVER
                    if (GameMain.Server != null)
                    {
                        item.CreateServerEvent(this);
                    }
#endif

                    networkUpdateTimer = 0.1f;
                    unsentChanges      = false;
                }
            }

            controlledSub = item.Submarine;
            var sonar = item.GetComponent <Sonar>();
            if (sonar != null && sonar.UseTransducers)
            {
                controlledSub = sonar.ConnectedTransducers.Any() ? sonar.ConnectedTransducers.First().Item.Submarine : null;
            }

            currPowerConsumption = powerConsumption;

            if (Voltage < MinVoltage)
            {
                return;
            }

            if (user != null && user.Removed)
            {
                user = null;
            }

            ApplyStatusEffects(ActionType.OnActive, deltaTime, null);

            float userSkill = 0.0f;
            if (user != null && controlledSub != null &&
                (user.SelectedConstruction == item || item.linkedTo.Contains(user.SelectedConstruction)))
            {
                userSkill = user.GetSkillLevel("helm") / 100.0f;
            }

            // override autopilot pathing while the AI rams, and go full speed ahead
            if (AIRamTimer > 0f)
            {
                AIRamTimer    -= deltaTime;
                TargetVelocity = GetSteeringVelocity(AITacticalTarget, 0f);
            }
            else if (AutoPilot)
            {
                UpdateAutoPilot(deltaTime);
                float throttle = 1.0f;
                if (controlledSub != null)
                {
                    //if the sub is heading in the correct direction, throttle the speed according to the user's skill
                    //if it's e.g. sinking due to extra water, don't throttle, but allow emptying up the ballast completely
                    throttle = MathHelper.Clamp(Vector2.Dot(controlledSub.Velocity, TargetVelocity) / 100.0f, 0.0f, 1.0f);
                }
                float maxSpeed = MathHelper.Lerp(AutoPilotMaxSpeed, AIPilotMaxSpeed, userSkill) * 100.0f;
                TargetVelocity = TargetVelocity.ClampLength(MathHelper.Lerp(100.0f, maxSpeed, throttle));
            }
            else
            {
                showIceSpireWarning = false;
                if (user != null && user.Info != null &&
                    user.SelectedConstruction == item &&
                    controlledSub != null && controlledSub.Velocity.LengthSquared() > 0.01f)
                {
                    IncreaseSkillLevel(user, deltaTime);
                }

                Vector2 velocityDiff = steeringInput - targetVelocity;
                if (velocityDiff != Vector2.Zero)
                {
                    if (steeringAdjustSpeed >= 0.99f)
                    {
                        TargetVelocity = steeringInput;
                    }
                    else
                    {
                        float steeringChange = 1.0f / (1.0f - steeringAdjustSpeed);
                        steeringChange *= steeringChange * 10.0f;

                        TargetVelocity += Vector2.Normalize(velocityDiff) *
                                          Math.Min(steeringChange * deltaTime, velocityDiff.Length());
                    }
                }
            }

            float velX = targetVelocity.X;
            if (controlledSub != null && controlledSub.FlippedX)
            {
                velX *= -1;
            }
            item.SendSignal(new Signal(velX.ToString(CultureInfo.InvariantCulture), sender: user), "velocity_x_out");

            float velY = MathHelper.Lerp((neutralBallastLevel * 100 - 50) * 2, -100 * Math.Sign(targetVelocity.Y), Math.Abs(targetVelocity.Y) / 100.0f);
            item.SendSignal(new Signal(velY.ToString(CultureInfo.InvariantCulture), sender: user), "velocity_y_out");

            // converts the controlled sub's velocity to km/h and sends it.
            if (controlledSub is { } sub)
            {
                item.SendSignal(new Signal((ConvertUnits.ToDisplayUnits(sub.Velocity.X * Physics.DisplayToRealWorldRatio) * 3.6f).ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_velocity_x");
                item.SendSignal(new Signal((ConvertUnits.ToDisplayUnits(sub.Velocity.Y * Physics.DisplayToRealWorldRatio) * -3.6f).ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_velocity_y");

                item.SendSignal(new Signal((sub.WorldPosition.X * Physics.DisplayToRealWorldRatio).ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_position_x");
                item.SendSignal(new Signal(sub.RealWorldDepth.ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_position_y");
            }

            // if our tactical AI pilot has left, revert back to maintaining position
            if (navigateTactically && (user == null || user.SelectedConstruction != item))
            {
                navigateTactically = false;
                AIRamTimer         = 0f;
                SetMaintainPosition();
            }
        }
示例#16
0
 public void SetVelocity(TargetVelocity newVel)
 {
     velocity = newVel;
     gridTargetIcon.velocity     = velocity;
     timelineTargetIcon.velocity = velocity;
 }