Ejemplo n.º 1
0
        public static void Create(
            Vector2D sourcePosition,
            Vector2D targetPosition,
            double traceStartWorldOffset,
            ITextureResource texture,
            double beamWidth,
            Vector2D originOffset,
            double duration,
            bool endsWithHit,
            double fadeInDistance,
            double fadeOutDistanceHit,
            double fadeOutDistanceNoHit,
            BlendMode blendMode)
        {
            var deltaPos        = targetPosition - sourcePosition;
            var length          = deltaPos.Length;
            var fadeInFraction  = fadeInDistance / length;
            var fadeOutFraction = endsWithHit
                                      ? fadeOutDistanceHit / length
                                      : fadeOutDistanceNoHit / length;

            if (fadeInFraction > 0.333 ||
                fadeOutFraction > 0.333)
            {
                // no sense in displaying such a short beam
                return;
            }

            var sceneObject = Client.Scene.CreateSceneObject(nameof(ComponentWeaponEnergyBeam));
            var component   = sceneObject.AddComponent <ComponentWeaponEnergyBeam>();

            ComponentWeaponTrace.CalculateAngleAndDirection(deltaPos,
                                                            out var angleRad,
                                                            out var normalizedRay);

            // offset start position of the ray
            sourcePosition += normalizedRay * traceStartWorldOffset;

            sceneObject.Position = sourcePosition;

            component.beamOriginOffset = originOffset;
            component.beamWidth        = beamWidth;
            component.primaryRendererDefaultPositionOffset = Vector2D.Zero;
            component.spriteRendererLine.TextureResource   = texture;
            component.targetPosition = targetPosition;
            component.duration       = duration;

            component.renderingMaterial
            .EffectParameters
            .Set("Length", (float)length)
            .Set("FadeInFraction", (float)fadeInFraction)
            .Set("FadeOutFraction", (float)fadeOutFraction);

            component.spriteRendererLine.BlendMode = blendMode;

            component.Update(0);
        }
Ejemplo n.º 2
0
        public static void ClientOnWeaponHitOrTrace(
            ICharacter firingCharacter,
            IProtoItemWeapon protoWeapon,
            IProtoItemAmmo protoAmmo,
            IProtoCharacter protoCharacter,
            Vector2Ushort fallbackCharacterPosition,
            IReadOnlyList <WeaponHitData> hitObjects,
            Vector2D endPosition,
            bool endsWithHit)
        {
            if (firingCharacter is not null &&
                !firingCharacter.IsInitialized)
            {
                firingCharacter = null;
            }

            var weaponTracePreset = protoWeapon.FireTracePreset
                                    ?? protoAmmo?.FireTracePreset;
            var worldPositionSource = SharedCalculateWeaponShotWorldPositon(
                firingCharacter,
                protoWeapon,
                protoCharacter,
                fallbackCharacterPosition.ToVector2D(),
                hasTrace: weaponTracePreset?.HasTrace ?? false);

            protoWeapon.ClientOnWeaponHitOrTrace(firingCharacter,
                                                 worldPositionSource,
                                                 protoWeapon,
                                                 protoAmmo,
                                                 protoCharacter,
                                                 fallbackCharacterPosition,
                                                 hitObjects,
                                                 endPosition,
                                                 endsWithHit);

            if (weaponTracePreset?.HasTrace ?? false)
            {
                ComponentWeaponTrace.Create(weaponTracePreset,
                                            worldPositionSource,
                                            endPosition,
                                            hasHit: endsWithHit,
                                            lastHitData: hitObjects.LastOrDefault(t => t.WorldObject is not null));
            }

            foreach (var hitData in hitObjects)
            {
                var hitWorldObject = hitData.WorldObject;
                if (hitWorldObject is not null &&
                    !hitWorldObject.IsInitialized)
                {
                    hitWorldObject = null;
                }

                var protoWorldObject = hitData.FallbackProtoWorldObject;

                double delay;
                {
                    var worldObjectPosition = CalculateWorldObjectPosition(hitWorldObject, hitData);
                    delay = weaponTracePreset?.HasTrace ?? false
                                ? SharedCalculateTimeToHit(weaponTracePreset,
                                                           worldPositionSource : worldPositionSource,
                                                           endPosition : worldObjectPosition
                                                           + hitData.HitPoint.ToVector2D())
                                : 0;
                }

                ClientTimersSystem.AddAction(
                    delay,
                    () =>
                {
                    // re-calculate the world object position
                    var worldObjectPosition = CalculateWorldObjectPosition(hitWorldObject, hitData);

                    var fireScatterPreset = protoAmmo?.OverrideFireScatterPreset
                                            ?? protoWeapon.FireScatterPreset;
                    var projectilesCount = fireScatterPreset.ProjectileAngleOffets.Length;

                    var objectMaterial = hitData.FallbackObjectMaterial;
                    if (hitWorldObject is ICharacter hitCharacter &&
                        hitCharacter.IsInitialized)
                    {
                        objectMaterial = ((IProtoCharacterCore)hitCharacter.ProtoCharacter)
                                         .SharedGetObjectMaterialForCharacter(hitCharacter);
                    }

                    protoWeapon.ClientPlayWeaponHitSound(hitWorldObject,
                                                         protoWorldObject,
                                                         fireScatterPreset,
                                                         objectMaterial,
                                                         worldObjectPosition);

                    if (weaponTracePreset is null)
                    {
                        return;
                    }

                    var randomRotation = !weaponTracePreset.HasTrace;
                    double?angleRad    = null;
                    if (!randomRotation)
                    {
                        var deltaPos = endPosition - worldPositionSource;
                        ComponentWeaponTrace.CalculateAngleAndDirection(deltaPos,
                                                                        out var angleRadLocal,
                                                                        out _);
                        angleRad = angleRadLocal;
                    }

                    ClientAddHitSparks(weaponTracePreset.HitSparksPreset,
                                       hitData,
                                       hitWorldObject,
                                       protoWorldObject,
                                       worldObjectPosition,
                                       projectilesCount,
                                       objectMaterial,
                                       randomizeHitPointOffset: !weaponTracePreset.HasTrace,
                                       randomRotation: randomRotation,
                                       rotationAngleRad: angleRad,
                                       drawOrder: weaponTracePreset.DrawHitSparksAsLight
                                                          ? DrawOrder.Light
                                                          : DrawOrder.Default);
                });