Пример #1
0
        public WeaponFireTracePreset(
            string traceTexturePath,
            IReadOnlyWeaponHitSparksPreset hitSparksPreset,
            double traceSpeed,
            ushort traceSpriteWidthPixels,
            int traceStartOffsetPixels,
            double traceStartScaleSpeedExponent = 1.0,
            double traceEndFadeOutExponent      = 1.0,
            bool useScreenBlending    = false,
            bool?drawHitSparksAsLight = null)
        {
            this.TraceTexture = traceTexturePath is not null
                                    ? new TextureResource(traceTexturePath, isTransparent: true)
                                    : null;

            this.TraceSpeed      = traceSpeed;
            this.HitSparksPreset = hitSparksPreset;

            this.TraceStartScaleSpeedExponent = traceStartScaleSpeedExponent;
            this.TraceEndFadeOutExponent      = traceEndFadeOutExponent;

            this.TraceWorldLength      = traceSpriteWidthPixels / 256.0;
            this.TraceStartWorldOffset = traceStartOffsetPixels / 256.0;

            this.TraceMinDistance = this.TraceWorldLength * 0.5;

            this.UseScreenBlending = useScreenBlending;

            this.DrawHitSparksAsLight = drawHitSparksAsLight ?? this.HasTrace;
        }
Пример #2
0
        public static void ClientAddHitSparks(
            IReadOnlyWeaponHitSparksPreset hitSparksPreset,
            WeaponHitData hitData,
            IWorldObject hitWorldObject,
            IProtoWorldObject protoWorldObject,
            Vector2D worldObjectPosition,
            int projectilesCount,
            ObjectMaterial objectMaterial,
            bool randomizeHitPointOffset,
            bool randomRotation,
            DrawOrder drawOrder,
            double scale = 1.0,
            double animationFrameDuration = 2 / 60.0)
        {
            var sceneObject = Api.Client.Scene.CreateSceneObject("Temp_HitSparks");

            sceneObject.Position = worldObjectPosition;
            var hitPoint = hitData.HitPoint.ToVector2D();

            if (!hitData.IsCliffsHit)
            {
                // move hitpoint a bit closer to the center of the object
                hitPoint = WeaponSystem.SharedOffsetHitWorldPositionCloserToObjectCenter(
                    hitWorldObject,
                    protoWorldObject,
                    hitPoint,
                    isRangedWeapon: randomizeHitPointOffset);
            }

            var sparksEntry = hitSparksPreset.GetForMaterial(objectMaterial);

            if (projectilesCount == 1 &&
                randomizeHitPointOffset &&
                sparksEntry.AllowRandomizedHitPointOffset)
            {
                // randomize hitpoint a bit by adding a little random offset
                var maxOffsetDistance = 0.2;
                var range             = maxOffsetDistance * RandomHelper.NextDouble();
                var angleRad          = 2 * Math.PI * RandomHelper.NextDouble();
                var randomOffset      = new Vector2D(range * Math.Cos(angleRad),
                                                     range * Math.Sin(angleRad));

                hitPoint += randomOffset;
            }

            var componentSpriteRender = Api.Client.Rendering.CreateSpriteRenderer(
                sceneObject,
                positionOffset: hitPoint,
                spritePivotPoint: (0.5, sparksEntry.PivotY),
                drawOrder: drawOrder);

            componentSpriteRender.DrawOrderOffsetY = -hitPoint.Y;
            componentSpriteRender.Scale            = (float)scale * Math.Pow(1.0 / projectilesCount, 0.35);

            if (sparksEntry.UseScreenBlending)
            {
                componentSpriteRender.BlendMode = BlendMode.Screen;
            }

            if (randomRotation)
            {
                componentSpriteRender.RotationAngleRad = (float)(RandomHelper.NextDouble() * 2 * Math.PI);
            }

            var componentAnimator = sceneObject.AddComponent <ClientComponentSpriteSheetAnimator>();
            var hitSparksEntry    = sparksEntry;

            componentAnimator.Setup(
                componentSpriteRender,
                hitSparksEntry.SpriteSheetAnimationFrames,
                frameDurationSeconds: animationFrameDuration,
                isLooped: false);

            var totalAnimationDuration = animationFrameDuration * componentAnimator.FramesCount;
            var totalDurationWithLight = 0.15 + totalAnimationDuration;

            if (hitSparksEntry.LightColor.HasValue)
            {
                // create light spot (even for melee weapons)
                var lightSource = ClientLighting.CreateLightSourceSpot(
                    sceneObject,
                    color: hitSparksEntry.LightColor.Value,
                    spritePivotPoint: (0.5, 0.5),
                    size: 7,
                    // we don't want to display nickname/healthbar for the firing character, it's too quick anyway
                    logicalSize: 0,
                    positionOffset: hitPoint);

                ClientComponentOneShotLightAnimation.Setup(lightSource, totalDurationWithLight);
            }

            componentSpriteRender.Destroy(totalAnimationDuration);
            componentAnimator.Destroy(totalAnimationDuration);

            sceneObject.Destroy(totalDurationWithLight);
        }