Esempio n. 1
0
    protected override void Update(Entity entity, HitCollisionOwner hitCollisionOwner, DestructibleProp prop, DestructablePropReplicatedState replicatedState)
    {
        if (prop.health <= 0)
        {
            return;
        }

        if (hitCollisionOwner.damageEvents.Count == 0)
        {
            return;
        }

        var instigator = Entity.Null;

        foreach (var damageEvent in hitCollisionOwner.damageEvents)
        {
            prop.health -= damageEvent.damage;

            if (damageEvent.instigator != Entity.Null)
            {
                instigator = damageEvent.instigator;
            }

            if (prop.health < 0)
            {
                break;
            }
        }
        hitCollisionOwner.damageEvents.Clear();

        if (prop.health <= 0)
        {
            hitCollisionOwner.collisionEnabled = false;

            foreach (var gameObject in prop.collision)
            {
                gameObject.SetActive(false);
            }

            replicatedState.destroyedTick = m_world.worldTime.tick;

            // Create splash damage
            if (prop.splashDamage.radius > 0)
            {
                var collisionMask = ~0;
                if (instigator != Entity.Null && EntityManager.HasComponent <Character>(instigator))
                {
                    var character = EntityManager.GetComponentObject <Character>(instigator);
                    collisionMask = ~(1 << character.teamId);
                }

                var splashCenter = prop.transform.position + prop.splashDamageOffset;
                SplashDamageRequest.Create(PostUpdateCommands, m_world.worldTime.tick, instigator, splashCenter, collisionMask, prop.splashDamage);
            }
        }
    }
Esempio n. 2
0
    public static void Create(EntityCommandBuffer commandBuffer, int tick, Entity instigator, float3 center,
                              int collisionMask, SplashDamageSettings settings)
    {
        var request = new SplashDamageRequest
        {
            instigator    = instigator,
            tick          = tick,
            center        = center,
            collisionMask = collisionMask,
            settings      = settings
        };

        commandBuffer.AddComponent(commandBuffer.CreateEntity(), request);
    }
Esempio n. 3
0
        protected override void OnUpdate()
        {
            var time          = ServerGameLoop.Instance.GameWorld.worldTime;
            var queryReciever = ServerGameLoop.Instance.ECSWorld.GetExistingSystem <RaySphereQueryReciever>();

            var grenadeEntityArray = grenadeQuery.GetEntityArraySt();
            var settingsArray      = grenadeQuery.GetComponentDataArraySt <GrenadeSimSettings>();
            var internalStateArray = grenadeQuery.GetComponentDataArraySt <GrenadeInternalState>();

            for (var i = 0; i < internalStateArray.Length; i++)
            {
                var internalState = internalStateArray[i];
                var entity        = grenadeEntityArray[i];

                if (internalState.active == 0)
                {
                    // Keep grenades around for a short duration so shortlived grenades gets a chance to get replicated
                    // and explode effect played

                    if (time.DurationSinceTick(internalState.explodeTick) > 1.0f)
                    {
                        // TODO: LZ:
                        // World.RequestDespawn(PostUpdateCommands, entity);
                        Debug.Log(string.Format("LZ: Grenade {0} should be destroyed!", entity.ToString()));
                        var tr = EntityManager.GetComponentObject <Transform>(entity);

                        if (tr != null)
                        {
                            Object.Destroy(tr.gameObject);
                        }
                        else
                        {
                            EntityManager.DestroyEntity(entity);
                        }
                    }

                    continue;
                }

                var settings          = settingsArray[i];
                var hitCollisionOwner = Entity.Null;
                if (internalState.rayQueryId != -1)
                {
                    RaySphereQueryReciever.Query       query;
                    RaySphereQueryReciever.QueryResult queryResult;
                    queryReciever.GetResult(internalState.rayQueryId, out query, out queryResult);
                    internalState.rayQueryId = -1;

                    // If grenade hit something that was no hitCollision it is environment and grenade should bounce
                    if (queryResult.hit == 1 && queryResult.hitCollisionOwner == Entity.Null)
                    {
                        var moveDir = math.normalize(internalState.velocity);
                        var moveVel = math.length(internalState.velocity);

                        internalState.position = queryResult.hitPoint + queryResult.hitNormal * settings.collisionRadius;

                        moveDir = Vector3.Reflect(moveDir, queryResult.hitNormal);
                        internalState.velocity = moveDir * moveVel * settings.bounciness;

                        // TODO: LZ:
                        //      Figure out a nice way to send the bounce event to the client
                        //      so the client can play the bounce sound at the correct time
#if false
                        if (moveVel > 1.0f)
                        {
                            interpolatedState.bouncetick = m_world.worldTime.tick;
                        }
#endif
                    }

                    if (queryResult.hitCollisionOwner != Entity.Null)
                    {
                        internalState.position = queryResult.hitPoint;
                    }

                    hitCollisionOwner = queryResult.hitCollisionOwner;
                }

                // Should we explode ?
                var timeout = time.DurationSinceTick(internalState.startTick) > settings.maxLifetime;
                if (timeout || hitCollisionOwner != Entity.Null)
                {
                    internalState.active      = 0;
                    internalState.explodeTick = time.tick;
                    Debug.Log(string.Format("LZ: Grenade {0} explode!", entity.ToString()));

                    if (settings.splashDamage.radius > 0)
                    {
                        var collisionMask = ~(1 << internalState.teamId);

                        // TODO: LZ:
                        //      calculate damage
#if false
                        SplashDamageRequest.Create(PostUpdateCommands, time.tick, internalState.owner, internalState.position,
                                                   collisionMask, settings.splashDamage);
#endif
                    }
                }

                EntityManager.SetComponentData(entity, internalState);

                //  internal state ==> ghost component
                Translation translation = new Translation {
                    Value = internalState.position
                };
                EntityManager.SetComponentData(entity, translation);

                // represent it on the server
                Transform representationTransform = EntityManager.GetComponentObject <Transform>(entity);
                representationTransform.position = internalState.position;
            }
        }
Esempio n. 4
0
    protected override void OnUpdate()
    {
        var entityArray         = Group.GetEntityArraySt();
        var hitCollArray        = Group.GetComponentDataArraySt <HitCollisionOwnerData>();
        var propArray           = Group.ToComponentArray <DestructibleProp>();
        var replicatedDataArray = Group.GetComponentDataArraySt <DestructablePropReplicatedData>();

        for (int i = 0; i < entityArray.Length; i++)
        {
            var prop = propArray[i];

            if (prop.health <= 0)
            {
                continue;
            }

            var entity       = entityArray[i];
            var damageBuffer = EntityManager.GetBuffer <DamageEvent>(entity);

            if (damageBuffer.Length == 0)
            {
                continue;
            }

            var instigator = Entity.Null;
            for (int j = 0; j < damageBuffer.Length; j++)
            {
                var damageEvent = damageBuffer[j];
                prop.health -= damageEvent.damage;

                if (damageEvent.instigator != Entity.Null)
                {
                    instigator = damageEvent.instigator;
                }

                if (prop.health < 0)
                {
                    break;
                }
            }
            damageBuffer.Clear();

            if (prop.health <= 0)
            {
                var replicatedState = replicatedDataArray[i];

                var hitCollOwner = hitCollArray[i];
                hitCollOwner.collisionEnabled = 0;
                EntityManager.SetComponentData(entity, hitCollOwner);

                foreach (var gameObject in prop.collision)
                {
                    gameObject.SetActive(false);
                }

                replicatedState.destroyedTick = m_world.worldTime.tick;

                // Create splash damage
                if (prop.splashDamage.radius > 0)
                {
                    var collisionMask = ~0;
                    if (instigator != Entity.Null && EntityManager.HasComponent <Character>(instigator))
                    {
                        var character = EntityManager.GetComponentObject <Character>(instigator);
                        collisionMask = ~(1 << character.teamId);
                    }

                    var splashCenter = prop.transform.position + prop.splashDamageOffset;
                    SplashDamageRequest.Create(PostUpdateCommands, m_world.worldTime.tick, instigator, splashCenter,
                                               collisionMask, prop.splashDamage);
                }

                EntityManager.SetComponentData(entity, replicatedState);
            }
        }
    }
Esempio n. 5
0
    protected override void OnUpdate()
    {
        Profiler.BeginSample("FinalizeGrenadeMovement");

        var time          = m_world.worldTime;
        var queryReciever = World.GetExistingManager <RaySphereQueryReciever>();

        var grenadeEntityArray     = Group.GetEntityArray();
        var settingsArray          = Group.GetComponentDataArray <Grenade.Settings>();
        var internalStateArray     = Group.GetComponentDataArray <Grenade.InternalState>();
        var interpolatedStateArray = Group.GetComponentDataArray <Grenade.InterpolatedState>();

        for (var i = 0; i < internalStateArray.Length; i++)
        {
            var internalState = internalStateArray[i];
            var entity        = grenadeEntityArray[i];

            if (internalState.active == 0)
            {
                // Keep grenades around for a short duration so shortlived grenades gets a chance to get replicated
                // and explode effect played

                if (m_world.worldTime.DurationSinceTick(internalState.explodeTick) > 1.0f)
                {
                    m_world.RequestDespawn(PostUpdateCommands, entity);
                }

                continue;
            }

            var settings          = settingsArray[i];
            var interpolatedState = interpolatedStateArray[i];
            var hitCollisionOwner = Entity.Null;
            if (internalState.rayQueryId != -1)
            {
                RaySphereQueryReciever.Query       query;
                RaySphereQueryReciever.QueryResult queryResult;
                queryReciever.GetResult(internalState.rayQueryId, out query, out queryResult);
                internalState.rayQueryId = -1;

                // If grenade hit something that was no hitCollision it is environment and grenade should bounce
                if (queryResult.hit == 1 && queryResult.hitCollisionOwner == Entity.Null)
                {
                    var moveDir = math.normalize(internalState.velocity);
                    var moveVel = math.length(internalState.velocity);

                    internalState.position = queryResult.hitPoint + queryResult.hitNormal * settings.collisionRadius;

                    moveDir = Vector3.Reflect(moveDir, queryResult.hitNormal);
                    internalState.velocity = moveDir * moveVel * settings.bounciness;

                    if (moveVel > 1.0f)
                    {
                        interpolatedState.bouncetick = m_world.worldTime.tick;
                    }
                }

                if (queryResult.hitCollisionOwner != Entity.Null)
                {
                    internalState.position = queryResult.hitPoint;
                }

                hitCollisionOwner = queryResult.hitCollisionOwner;
            }

            // Should we explode ?
            var timeout = time.DurationSinceTick(internalState.startTick) > settings.maxLifetime;
            if (timeout || hitCollisionOwner != Entity.Null)
            {
                internalState.active       = 0;
                internalState.explodeTick  = time.tick;
                interpolatedState.exploded = 1;

                if (settings.splashDamage.radius > 0)
                {
                    var collisionMask = ~(1 << internalState.teamId);

                    SplashDamageRequest.Create(PostUpdateCommands, time.tick, internalState.owner, internalState.position,
                                               collisionMask, settings.splashDamage);
                }
            }

            interpolatedState.position = internalState.position;

            DebugDraw.Sphere(interpolatedState.position, settings.collisionRadius, Color.red);


            EntityManager.SetComponentData(entity, internalState);
            EntityManager.SetComponentData(entity, interpolatedState);
        }

        Profiler.EndSample();
    }
Esempio n. 6
0
    protected override void OnUpdate()
    {
        var entityArray         = ProjectileGroup.GetEntityArray();
        var projectileDataArray = ProjectileGroup.GetComponentDataArray <ProjectileData>();
        var queryReciever       = World.GetExistingManager <RaySphereQueryReciever>();

        for (var i = 0; i < projectileDataArray.Length; i++)
        {
            var projectileData = projectileDataArray[i];

            if (projectileData.impactTick > 0)
            {
                continue;
            }

            RaySphereQueryReciever.Query  query;
            RaySphereQueryReciever.Result result;
            queryReciever.GetResult(projectileData.rayQueryId, out query, out result);

            var projectileVec = projectileData.endPos - projectileData.startPos;
            var projectileDir = Vector3.Normalize(projectileVec);
            var newPosition   = (Vector3)projectileData.position + projectileDir * query.distance;

            var impact = result.hit == 1;
            if (impact)
            {
                projectileData.impacted     = 1;
                projectileData.impactPos    = result.hitPoint;
                projectileData.impactNormal = result.hitNormal;
                projectileData.impactTick   = m_world.worldTime.tick;

                var damageInstigator = projectileData.projectileOwner;
                //                GameDebug.Assert(damageInstigator == Entity.Null || !EntityManager.Exists(damageInstigator) || EntityManager.HasComponent<Character>(damageInstigator),"Damage instigator is not a character");

                var collisionHit = result.hitCollisionOwner != Entity.Null;
                if (collisionHit)
                {
                    if (damageInstigator != Entity.Null)
                    {
                        if (EntityManager.HasComponent <HitCollisionOwner>(result.hitCollisionOwner))
                        {
                            var hitCollisionOwner = EntityManager.GetComponentObject <HitCollisionOwner>(result.hitCollisionOwner);
                            hitCollisionOwner.damageEvents.Add(new DamageEvent(damageInstigator, projectileData.settings.impactDamage, projectileDir, projectileData.settings.impactImpulse));
                        }
                    }
                }

                if (projectileData.settings.splashDamage.radius > 0)
                {
                    if (damageInstigator != Entity.Null)
                    {
                        var collisionMask = ~(1 << projectileData.teamId);
                        SplashDamageRequest.Create(PostUpdateCommands, query.hitCollisionTestTick, damageInstigator, result.hitPoint, collisionMask, projectileData.settings.splashDamage);
                    }
                }

                newPosition = result.hitPoint;
            }

            if (ProjectileModuleServer.drawDebug.IntValue == 1)
            {
                var color = impact ? Color.red : Color.green;
                Debug.DrawLine(projectileData.position, newPosition, color, 2);
                DebugDraw.Sphere(newPosition, 0.1f, color, impact ? 2 : 0);
            }

            projectileData.position = newPosition;
            PostUpdateCommands.SetComponent(entityArray[i], projectileData);
        }
    }
Esempio n. 7
0
    protected override void OnUpdate()
    {
        var entityArray         = ProjectileGroup.GetEntityArray();
        var projectileDataArray = ProjectileGroup.GetComponentDataArray <ProjectileData>();
        var queryReciever       = World.GetExistingManager <RaySphereQueryReciever>();

        for (var i = 0; i < projectileDataArray.Length; i++)
        {
            var projectileData = projectileDataArray[i];

            if (projectileData.impactTick > 0)
            {
                continue;
            }

            RaySphereQueryReciever.Query       query;
            RaySphereQueryReciever.QueryResult queryResult;
            queryReciever.GetResult(projectileData.rayQueryId, out query, out queryResult);

            var projectileVec = projectileData.endPos - projectileData.startPos;
            var projectileDir = Vector3.Normalize(projectileVec);
            var newPosition   = (Vector3)projectileData.position + projectileDir * query.distance;

            var impact = queryResult.hit == 1;
            if (impact)
            {
                projectileData.impacted     = 1;
                projectileData.impactPos    = queryResult.hitPoint;
                projectileData.impactNormal = queryResult.hitNormal;
                projectileData.impactTick   = m_world.worldTime.tick;

                // Owner can despawn while projectile is in flight, so we need to make sure we dont send non existing instigator
                var damageInstigator = EntityManager.Exists(projectileData.projectileOwner) ? projectileData.projectileOwner : Entity.Null;

                var collisionHit = queryResult.hitCollisionOwner != Entity.Null;
                if (collisionHit)
                {
                    if (damageInstigator != Entity.Null)
                    {
                        if (EntityManager.HasComponent <DamageEvent>(queryResult.hitCollisionOwner))
                        {
                            var damageEventBuffer = EntityManager.GetBuffer <DamageEvent>(queryResult.hitCollisionOwner);
                            DamageEvent.AddEvent(damageEventBuffer, damageInstigator, projectileData.settings.impactDamage, projectileDir, projectileData.settings.impactImpulse);
                        }
                    }
                }

                if (projectileData.settings.splashDamage.radius > 0)
                {
                    if (damageInstigator != Entity.Null)
                    {
                        var collisionMask = ~(1 << projectileData.teamId);
                        SplashDamageRequest.Create(PostUpdateCommands, query.hitCollisionTestTick, damageInstigator, queryResult.hitPoint, collisionMask, projectileData.settings.splashDamage);
                    }
                }

                newPosition = queryResult.hitPoint;
            }

            if (ProjectileModuleServer.drawDebug.IntValue == 1)
            {
                var color = impact ? Color.red : Color.green;
                Debug.DrawLine(projectileData.position, newPosition, color, 2);
                DebugDraw.Sphere(newPosition, 0.1f, color, impact ? 2 : 0);
            }

            projectileData.position = newPosition;
            PostUpdateCommands.SetComponent(entityArray[i], projectileData);
        }
    }
Esempio n. 8
0
    protected override void OnUpdate()
    {
        Profiler.BeginSample("FinalizeGrenadeMovement");

        var time                = m_world.worldTime;
        var queryReciever       = World.GetExistingManager <RaySphereQueryReciever>();
        var grenadeArray        = Group.GetComponentArray <Grenade>();
        var grenadePresentArray = Group.GetComponentArray <GrenadePresentation>();

        for (var i = 0; i < grenadeArray.Length; i++)
        {
            var grenade = grenadeArray[i];
            if (!grenade.active)
            {
                // Keep grenades around for a short duration so shortlived grenades gets a chance to get replicated
                // and explode effect played
                if (m_world.worldTime.DurationSinceTick(grenade.explodeTick) > 1.0f)
                {
                    m_world.RequestDespawn(grenade.gameObject, PostUpdateCommands);
                }

                continue;
            }

            var presentation      = grenadePresentArray[i];
            var hitCollisionOwner = Entity.Null;
            if (grenade.rayQueryId != -1)
            {
                RaySphereQueryReciever.Query  query;
                RaySphereQueryReciever.Result result;
                queryReciever.GetResult(grenade.rayQueryId, out query, out result);
                grenade.rayQueryId = -1;

                // If grenade hit something that was no hitCollision it is environment and grenade should bounce
                if (result.hit == 1 && result.hitCollisionOwner == Entity.Null)
                {
                    float3 moveDir = grenade.velocity.normalized;
                    var    moveVel = grenade.velocity.magnitude;

                    grenade.position = result.hitPoint + result.hitNormal * grenade.collisionRadius;

                    moveDir          = Vector3.Reflect(moveDir, result.hitNormal);
                    grenade.velocity = moveDir * moveVel * grenade.bounciness;

                    if (grenade.velocity.magnitude > 1.0f)
                    {
                        presentation.state.bouncetick = m_world.worldTime.tick;
                    }
                }

                if (result.hitCollisionOwner != Entity.Null)
                {
                    grenade.position = result.hitPoint;
                }

                hitCollisionOwner = result.hitCollisionOwner;
            }

            // Should we explode ?
            var timeout = time.DurationSinceTick(grenade.startTick) > grenade.maxLifetime;
            if (timeout || hitCollisionOwner != Entity.Null)
            {
                grenade.active              = false;
                grenade.explodeTick         = time.tick;
                presentation.state.exploded = true;

                if (grenade.splashDamage.radius > 0)
                {
                    var collisionMask = ~(1 << grenade.teamId);

                    SplashDamageRequest.Create(PostUpdateCommands, time.tick, grenade.owner, grenade.position,
                                               collisionMask, grenade.splashDamage);
                }
            }

            // Update presentation
            presentation.state.position = grenade.position;
        }

        Profiler.EndSample();
    }