public void ServerSetDroneTarget( IDynamicWorldObject objectDrone, IStaticWorldObject targetWorldObject, Vector2D fromStartPosition) { var targetObjectPosition = targetWorldObject.TilePosition; var publicState = GetPublicState(objectDrone); var targetDronePosition = targetObjectPosition.ToVector2D() + DroneTargetPositionHelper.GetTargetPosition(targetWorldObject); // ensure the drone will select a position on the side of the object var directionX = fromStartPosition.X - targetDronePosition.X; if (Math.Abs(directionX) < 0.5) { directionX = 0.5 * Math.Sign(directionX); } else if (Math.Abs(directionX) > 1.0) { directionX = 1.0 * Math.Sign(directionX); } if (targetWorldObject.ProtoGameObject is IProtoObjectTree) { // ensure the drone will always fly somewhere above below the tree // (a beam behind the tree doesn't look good) targetDronePosition -= (0, 0.5); directionX = Math.Sign(directionX) * 1.5; } else { // ensure the drone will always fly somewhere above the object targetDronePosition += (0, 0.5); } targetDronePosition += new Vector2D(directionX * this.BeamMaxLength, 0); publicState.SetTargetPosition(targetObjectPosition, targetDronePosition); CharacterDroneControlSystem.ServerUnregisterCurrentMining(objectDrone); }
public override void Update(double deltaTime) { if (this.dronePublicState.TargetObjectPosition.HasValue) { this.lastTargetPosition = this.dronePublicState.TargetObjectPosition.Value.ToVector2D(); if (this.hitWorldObject is null) { this.hitWorldObject = Client.World.GetTile(this.lastTargetPosition.Value.ToVector2Ushort()) .StaticObjects .FirstOrDefault(); } if (this.hitWorldObject != null) { var objectCenter = DroneTargetPositionHelper.GetTargetPosition(this.hitWorldObject); objectCenter = (objectCenter.X, objectCenter.Y * 0.5 + 0.2); this.lastTargetPosition += objectCenter; } } else { this.hitWorldObject = null; } if (this.hitWorldObject != null && this.soundEmitterMiningProcess.SoundResource is null) { this.soundEmitterMiningProcess.SoundResource = GetSourceResourceMiningProcess(this.hitWorldObject.ProtoStaticWorldObject); } var wasEnabled = this.spriteRendererLine.IsEnabled; var isBeamActive = this.dronePublicState.IsMining && this.lastTargetPosition.HasValue; this.alpha = MathHelper.LerpWithDeltaTime( this.alpha, isBeamActive ? 1 : 0, deltaTime: deltaTime, rate: 20); var isEnabled = this.alpha > 0.001; this.spriteRendererLine.IsEnabled = isEnabled; this.spriteRendererOrigin.IsEnabled = isEnabled; this.soundEmitterMiningProcess.IsEnabled = isEnabled; if (!isEnabled) { if (wasEnabled) { // just disabled Api.Client.Audio.PlayOneShot(SourceResourceMiningEnd, this.SceneObject, MiningVolume); } return; } if (!wasEnabled) { // just enabled Api.Client.Audio.PlayOneShot(SourceResourceMiningStart, this.SceneObject, MiningVolume); } var alphaComponent = (byte)(this.alpha * byte.MaxValue); this.spriteRendererLine.Color = this.beamColor.WithAlpha(alphaComponent); this.spriteRendererOrigin.Color = Color.FromArgb(alphaComponent, 0xFF, 0xFF, 0xFF); this.soundEmitterMiningProcess.Volume = (float)(this.alpha * MiningVolume); // update line start-end positions and rotation angle var currentBeamOriginOffset = this.beamOriginOffset + this.primaryRenderer.PositionOffset - this.primaryRendererDefaultPositionOffset; var lineStartWorldPosition = this.SceneObject.Position + currentBeamOriginOffset; // ReSharper disable once PossibleInvalidOperationException var lineEndWorldPosition = this.lastTargetPosition.Value; lineEndWorldPosition += this.GetMiningTargetMovementAnimation(deltaTime); var lineDirection = lineEndWorldPosition - lineStartWorldPosition; this.spriteRendererLine.PositionOffset = currentBeamOriginOffset; this.spriteRendererLine.RotationAngleRad = (float)-Math.Atan2(lineDirection.Y, lineDirection.X); this.spriteRendererLine.Scale = (lineDirection.Length, this.beamWidth); this.spriteRendererLine.DrawOrderOffsetY = this.primaryRenderer.DrawOrderOffsetY; this.spriteRendererOrigin.PositionOffset = currentBeamOriginOffset; this.spriteRendererOrigin.Scale = this.beamWidth; this.spriteRendererOrigin.DrawOrderOffsetY = this.primaryRenderer.DrawOrderOffsetY; if (this.hitWorldObject is null) { return; } this.timeSinceLastHitSparks -= deltaTime; if (this.timeSinceLastHitSparks < 0) { WeaponSystemClientDisplay.ClientAddHitSparks( WeaponHitSparksPresets.LaserMining, new WeaponHitData(Vector2D.Zero), this.hitWorldObject, this.hitWorldObject.ProtoStaticWorldObject, worldObjectPosition: lineEndWorldPosition, projectilesCount: 1, objectMaterial: this.hitWorldObject.ProtoStaticWorldObject.SharedGetObjectMaterial(), randomizeHitPointOffset: false, randomRotation: true, drawOrder: DrawOrder.Light + 2, animationFrameDuration: 3 / 60.0); this.timeSinceLastHitSparks += HitSparksInterval; } }