Esempio n. 1
0
 // for cliffs hit
 public WeaponHitData(Vector2D hitPosition)
 {
     this.WorldObject = null;
     this.IsCliffsHit = true;
     this.FallbackProtoWorldObject = null;
     this.FallbackTilePosition     = (Vector2Ushort)hitPosition;
     this.HitPoint = (hitPosition - this.FallbackTilePosition.ToVector2D()).ToVector2F();
     this.FallbackObjectMaterial = ObjectMaterial.Stone;
 }
Esempio n. 2
0
            // Optimized to minimize GC allocations.
            public bool Contains(IProtoWorldObject protoWorldObject)
            {
                foreach (var entry in this)
                {
                    if (ReferenceEquals(entry, protoWorldObject))
                    {
                        return(true);
                    }
                }

                return(false);
            }
Esempio n. 3
0
        private static IWorldObject ServerTrySpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition)
        {
            switch (protoObjectToSpawn)
            {
            case IProtoCharacterMob protoCharacterMob:
                return(Server.Characters.SpawnCharacter(protoCharacterMob,
                                                        spawnPosition.ToVector2D()));

            case IProtoStaticWorldObject protoStaticWorldObject:
                return(Server.World.CreateStaticWorldObject(protoStaticWorldObject, spawnPosition));

            default:
                throw new Exception("Unknown object type to spawn: " + protoObjectToSpawn);
            }
        }
Esempio n. 4
0
        private static bool ServerCheckCanSpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition)
        {
            switch (protoObjectToSpawn)
            {
            case IProtoCharacterMob _:
                return(ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(spawnPosition.ToVector2D(),
                                                                                   isPlayer: false));

            case IProtoStaticWorldObject protoStaticWorldObject:
                return(protoStaticWorldObject.CheckTileRequirements(spawnPosition,
                                                                    character: null,
                                                                    logErrors: false));

            default:
                throw new Exception("Unknown object type to spawn: " + protoObjectToSpawn);
            }
        }
Esempio n. 5
0
        public static Vector2D SharedOffsetHitWorldPositionCloserToObjectCenter(
            IWorldObject worldObject,
            IProtoWorldObject protoWorldObject,
            Vector2D hitPoint,
            bool isRangedWeapon)
        {
            var objectCenterPosition = worldObject?.PhysicsBody?.CalculateCenterOffsetForCollisionGroup(
                isRangedWeapon
                                               ? CollisionGroups.HitboxRanged
                                               : CollisionGroups.HitboxMelee)
                                       ?? protoWorldObject.SharedGetObjectCenterWorldOffset(worldObject);
            var coef   = isRangedWeapon ? 0.2 : 0.5;
            var offset = coef * (objectCenterPosition - hitPoint);

            offset    = offset.ClampMagnitude(0.5); // don't offset more than 0.5 tiles
            hitPoint += offset;
            return(hitPoint);
        }
Esempio n. 6
0
        private static bool ServerCheckCanSpawn(IProtoWorldObject protoObjectToSpawn, Vector2Ushort spawnPosition)
        {
            return(protoObjectToSpawn switch
            {
                IProtoCharacterMob
                => ServerCharacterSpawnHelper.IsPositionValidForCharacterSpawn(
                    spawnPosition.ToVector2D(),
                    isPlayer: false) &&
                !LandClaimSystem.SharedIsLandClaimedByAnyone(spawnPosition),

                IProtoStaticWorldObject protoStaticWorldObject
                // Please note: land claim check must be integrated in the object tile requirements
                => protoStaticWorldObject.CheckTileRequirements(
                    spawnPosition,
                    character: null,
                    logErrors: false),

                _ => throw new ArgumentOutOfRangeException("Unknown object type to spawn: " + protoObjectToSpawn)
            });
        public static ReadOnlySoundPreset <ObjectSound> SharedGetObjectSoundPreset(
            this IProtoWorldObject protoWorldObject)
        {
            if (protoWorldObject == null)
            {
                throw new ArgumentNullException(nameof(protoWorldObject));
            }

            if (protoWorldObject is IProtoWorldObjectWithSoundPresets protoWorldObjectWithSoundPresets)
            {
                return(protoWorldObjectWithSoundPresets.SoundPresetObject);
            }

            Api.Logger.Error(
                protoWorldObject
                + " type is not inherited from "
                + nameof(IProtoWorldObjectWithSoundPresets)
                + " - cannot get object sound preset. Using default (generic) sound preset instead.");
            return(ObjectsSoundsPresets.ObjectGeneric);
        }
Esempio n. 8
0
        public WeaponHitData(IWorldObject worldObject, Vector2F hitPoint)
        {
            this.WorldObject = worldObject;
            this.IsCliffsHit = false;
            this.FallbackProtoWorldObject = worldObject.ProtoWorldObject;
            this.FallbackTilePosition     = worldObject.TilePosition;
            this.HitPoint = hitPoint;

            if (worldObject is ICharacter character)
            {
                this.FallbackObjectMaterial = ((IProtoCharacterCore)character.ProtoCharacter)
                                              .SharedGetObjectMaterialForCharacter(character);
            }
            else if (worldObject.ProtoWorldObject is IProtoWorldObjectWithSoundPresets protoWorldObjectWithSoundPresets)
            {
                this.FallbackObjectMaterial = protoWorldObjectWithSoundPresets
                                              .ObjectMaterial;
            }
            else
            {
                this.FallbackObjectMaterial = ObjectMaterial.HardTissues;
            }
        }
Esempio n. 9
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);
        }
Esempio n. 10
0
 public static ObjectMaterial SharedGetObjectMaterial(this IProtoWorldObject protoWorldObject)
 {
     return(((IProtoWorldObjectWithSoundPresets)protoWorldObject).ObjectMaterial);
 }
Esempio n. 11
0
 public WeaponHitData(IWorldObject worldObject)
 {
     this.WorldObject = worldObject;
     this.FallbackProtoWorldObject = worldObject.ProtoWorldObject;
     this.FallbackTilePosition     = worldObject.TilePosition;
 }