Пример #1
0
        // Routine to send the collected collisions into the simulator.
        // Also handles removal of this from the collection of objects with collisions if
        //      there are no collisions from this object. Mechanism is create one last
        //      collision event to make collision_end work.
        // Called at taint time from within the Step() function thus no locking problems
        //      with CollisionCollection and ObjectsWithNoMoreCollisions.
        // Return 'true' if there were some actual collisions passed up
        public virtual bool SendCollisions()
        {
            bool ret = true;

            // throttle the collisions to the number of milliseconds specified in the subscription
            int nowTime = PhysicsScene.SimulationNowTime;

            if (nowTime >= NextCollisionOkTime)
            {
                NextCollisionOkTime = nowTime + SubscribedEventsMs;

                // We are called if we previously had collisions. If there are no collisions
                //   this time, send up one last empty event so OpenSim can sense collision end.
                if (CollisionCollection.Count == 0)
                {
                    // If I have no collisions this time, remove me from the list of objects with collisions.
                    ret = false;
                }

                // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
                base.SendCollisionUpdate(CollisionCollection);

                // The collisionCollection structure is passed around in the simulator.
                // Make sure we don't have a handle to that one and that a new one is used for next time.
                CollisionCollection = new CollisionEventUpdate();
            }
            return(ret);
        }
Пример #2
0
        // Send the collected collisions into the simulator.
        // Called at taint time from within the Step() function thus no locking problems
        //      with CollisionCollection and ObjectsWithNoMoreCollisions.
        // Called with BSScene.CollisionLock locked to protect the collision lists.
        // Return 'true' if there were some actual collisions passed up
        public virtual bool SendCollisions()
        {
            bool ret = true;

            // If no collisions this call but there were collisions last call, force the collision
            //     event to be happen right now so quick collision_end.
            bool force = (CollisionCollection.Count == 0 && CollisionsLastReported.Count != 0);

            // throttle the collisions to the number of milliseconds specified in the subscription
            if (force || (PhysScene.SimulationNowTime >= NextCollisionOkTime))
            {
                NextCollisionOkTime = PhysScene.SimulationNowTime + SubscribedEventsMs;

                // We are called if we previously had collisions. If there are no collisions
                //   this time, send up one last empty event so OpenSim can sense collision end.
                if (CollisionCollection.Count == 0)
                {
                    // If I have no collisions this time, remove me from the list of objects with collisions.
                    ret = false;
                }

                DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
                base.SendCollisionUpdate(CollisionCollection);

                // Remember the collisions from this tick for some collision specific processing.
                CollisionsLastReported = CollisionCollection;

                // The CollisionCollection instance is passed around in the simulator.
                // Make sure we don't have a handle to that one and that a new one is used for next time.
                //    This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here,
                //    a race condition is created for the other users of this instance.
                CollisionCollection = new CollisionEventUpdate();
            }
            return(ret);
        }
Пример #3
0
        public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
        {
            // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);

            // The following makes IsColliding() and IsCollidingGround() work
            _collidingStep = _scene.SimulationStep;
            if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
            {
                _collidingGroundStep = _scene.SimulationStep;
            }

            // throttle collisions to the rate specified in the subscription
            if (_subscribedEventsMs == 0)
            {
                return;                         // don't want collisions
            }
            int nowTime = _scene.SimulationNowTime;

            if (nowTime < (_lastCollisionTime + _subscribedEventsMs))
            {
                return;
            }
            _lastCollisionTime = nowTime;

            Dictionary <uint, ContactPoint> contactPoints = new Dictionary <uint, ContactPoint>();

            contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
            CollisionEventUpdate args = new CollisionEventUpdate(contactPoints);

            base.SendCollisionUpdate(args);
        }
Пример #4
0
 public void AddCollision(uint collideWith, ContactPoint contact)
 {
     if (CollisionEventsThisFrame == null)
     {
         CollisionEventsThisFrame = new CollisionEventUpdate();
     }
     CollisionEventsThisFrame.addCollider(collideWith, contact);
 }
Пример #5
0
 public void SendCollisions()
 {
     if (m_eventsubscription > 0)
     {
         base.SendCollisionUpdate(CollisionEventsThisFrame);
         CollisionEventsThisFrame = new CollisionEventUpdate();
     }
 }
Пример #6
0
            public void PhysicsActor_OnCollisionUpdate(EventArgs e)
            {
                if (HasLeftCombat)
                {
                    return;
                }

                if (e == null)
                {
                    return;
                }

                CollisionEventUpdate            collisionData = (CollisionEventUpdate)e;
                Dictionary <uint, ContactPoint> coldata       = collisionData.m_objCollisionList;

                UUID killerObj = UUID.Zero;

                foreach (uint localid in coldata.Keys)
                {
                    ISceneChildEntity part = m_part.ParentGroup.Scene.GetSceneObjectPart(localid);
                    if (part != null && part.ParentEntity.Damage != -1.0f)
                    {
                        if (part.ParentEntity.Damage > MaximumDamageToInflict)
                        {
                            part.ParentEntity.Damage = MaximumDamageToInflict;
                        }

                        Health -= part.ParentEntity.Damage;
                        if (Health <= 0.0f)
                        {
                            killerObj = part.UUID;
                        }
                    }
                    else
                    {
                        float Z = Math.Abs(m_part.Velocity.Z);
                        if (coldata[localid].PenetrationDepth >= 0.05f)
                        {
                            Health -= coldata[localid].PenetrationDepth * Z;
                        }
                    }

                    //Regenerate health (this is approx 1 sec)
                    if ((int)(Health + 0.0625) <= m_combatModule.MaximumHealth)
                    {
                        Health += 0.0625f;
                    }

                    if (Health > m_combatModule.MaximumHealth)
                    {
                        Health = m_combatModule.MaximumHealth;
                    }
                }
                if (Health <= 0)
                {
                    Die(killerObj);
                }
            }
Пример #7
0
        /// <summary>
        /// Sends collision events concerning this object to the simulator.
        /// </summary>
        /// <returns>Whether any collisions were sent to the simulator</returns>
        public virtual bool SendCollisions()
        {
            bool sendEndEvent;
            bool moreEvents = true;

            // Check to see if this object is supposed to be sending out
            // collision events
            if (SubscribedEventInterval <= 0)
            {
                // This means that events should not be sent out, so exit
                return(false);
            }

            // Check to see if there are no more collisions, but collisions
            // were sent out last call; if so, go ahead and send an empty
            // collision to signify the end of the collisions
            sendEndEvent = false;
            if (Collisions.Count == 0 && CollisionsLastReported.Count != 0)
            {
                sendEndEvent = true;
            }

            // Check to see if an end event needs to be sent or if the minimum
            // event interval has passed
            if (sendEndEvent || ParentScene.CurrentSimulationTime >=
                NextCollisionEventTime)
            {
                // Calculate the time for sending out the next collision update
                NextCollisionEventTime = ParentScene.CurrentSimulationTime +
                                         SubscribedEventInterval;

                // Send the collision event
                base.SendCollisionUpdate(Collisions);

                // Check to see if there are no more collision events to send
                if (Collisions.Count == 0)
                {
                    // Flag that there are no more collision events to send
                    moreEvents = false;
                }

                // Store the collisions reported in this update for later
                // reference
                CollisionsLastReported = Collisions;

                // Create a new event update that will accrue future collisions
                Collisions = new CollisionEventUpdate();
            }

            // Return whether this object has more collision events pending
            return(moreEvents);
        }
Пример #8
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="parentScene">The scene to which this object
        /// belongs</param>
        /// <param name="localID">The unique identifier of the object</param>
        /// <param name="name">The name of the object</param>
        /// <param name="typeName">The type of the object</param>
        /// <param name="config">The configuration used to initialize this
        /// object</param>
        protected RemotePhysicsObject(RemotePhysicsScene parentScene,
                                      uint localID, String name, String typeName,
                                      RemotePhysicsConfiguration config)
        {
            // Initialize the parent physics scene
            ParentScene = parentScene;

            // Indicate that this object has not been fully initialized
            IsInitialized = false;

            // Initialize the handle to the configuration that will be used
            // initialize other properties
            ParentConfiguration = config;

            // Initialize the local ID of this object
            LocalID = localID;

            // Initialize the name of this physics object
            // Usually this is the same name as the OpenSim object
            Name = name;

            // Initialize the type of this object in string form
            TypeName = typeName;

            // Initialize the gravity modifier to be 1.0, so that the
            // gravity of the scene will be unmodified when it affects
            // this object
            GravModifier = 1.0f;

            // Initialize the gravity vector
            Gravity = new OpenMetaverse.Vector3(0.0f, 0.0f, config.Gravity);

            // Indicate that the object is not hovering
            HoverActive = false;

            // Create the list of pending and sent collisions
            Collisions             = new CollisionEventUpdate();
            CollisionsLastReported = Collisions;

            // Initialize the collision steps to be invalid steps, since no
            // collision has occurred yet
            GroundCollisionStep = RemotePhysicsScene.InvalidStep;
            ObjectCollisionStep = RemotePhysicsScene.InvalidStep;
            LastCollisionStep   = RemotePhysicsScene.InvalidStep;

            // No collisions have occurred, so start the collision count at 0
            NumCollisions = 0;

            // Initialize the object that will ensure the thread safety of the
            // collision step data
            m_collisionStepLock = new Object();
        }
Пример #9
0
 public void SendCollisions()
 {
     if (m_eventsubscription >= m_requestedUpdateFrequency)
     {
         if (CollisionEventsThisFrame != null)
         {
             base.SendCollisionUpdate(CollisionEventsThisFrame);
         }
         CollisionEventsThisFrame = new CollisionEventUpdate();
         m_eventsubscription      = 0;
     }
     return;
 }
Пример #10
0
        protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName)
        {
            PhysicsScene   = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            TypeName       = typeName;

            Linkset = new BSLinkset(PhysicsScene, this);

            CollisionCollection = new CollisionEventUpdate();
            SubscribedEventsMs  = 0;
            CollidingStep       = 0;
            CollidingGroundStep = 0;
        }
Пример #11
0
    protected void BaseInitialize(BSScene parentScene, uint localID, string name, string typeName)
    {
        PhysicsScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        TypeName = typeName;

        Linkset = new BSLinkset(PhysicsScene, this);

        CollisionCollection = new CollisionEventUpdate();
        SubscribedEventsMs = 0;
        CollidingStep = 0;
        CollidingGroundStep = 0;
    }
Пример #12
0
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            IsInitialized = false;

            PhysScene      = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            Name           = name; // PhysicsActor also has the name of the object. Someday consolidate.
            TypeName       = typeName;

            // The collection of things that push me around
            PhysicalActors = new BSActorCollection(PhysScene);

            // Initialize variables kept in base.
            GravModifier = 1.0f;
            Gravity      = new OMV.Vector3(0f, 0f, BSParam.Gravity);
            HoverActive  = false;

            // We don't have any physical representation yet.
            PhysBody  = new BulletBody(localID);
            PhysShape = new BSShapeNull();

            UserSetCenterOfMassDisplacement = null;

            PrimAssetState = PrimAssetCondition.Unknown;

            // Default material type. Also sets Friction, Restitution and Density.
            SetMaterial((int)MaterialAttributes.Material.Wood);

            CollisionCollection    = new CollisionEventUpdate();
            CollisionsLastReported = CollisionCollection;
            CollisionsLastTick     = new CollisionEventUpdate();
            CollisionsLastTickStep = -1;

            SubscribedEventsMs = 0;
            // Crazy values that will never be true
            CollidingStep         = BSScene.NotASimulationStep;
            CollidingGroundStep   = BSScene.NotASimulationStep;
            CollisionAccumulation = BSScene.NotASimulationStep;
            ColliderIsMoving      = false;
            CollisionScore        = 0;

            // All axis free.
            LockedLinearAxis  = LockedAxisFree;
            LockedAngularAxis = LockedAxisFree;
        }
Пример #13
0
            public void PhysicsActor_OnCollisionUpdate(EventArgs e)
            {
                /*if (HasLeftCombat)
                 *  return;
                 */
                if (e == null)
                {
                    return;
                }

                CollisionEventUpdate collisionData = (CollisionEventUpdate)e;

                /*Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
                 *
                 * UUID killerObj = UUID.Zero;
                 * foreach (uint localid in coldata.Keys)
                 * {
                 *  ISceneChildEntity part = m_part.Scene.GetSceneObjectPart(localid);
                 *  if (part != null && part.ParentEntity.Damage != -1.0f)
                 *  {
                 *      if (part.ParentEntity.Damage > MaximumDamageToInflict)
                 *          part.ParentEntity.Damage = MaximumDamageToInflict;
                 *
                 *      Health -= part.ParentEntity.Damage;
                 *      if (Health <= 0.0f)
                 *          killerObj = part.UUID;
                 *  }
                 *  else
                 *  {
                 *      float Z = Math.Abs(m_part.Velocity.Z);
                 *      if (coldata[localid].PenetrationDepth >= 0.05f)
                 *          Health -= coldata[localid].PenetrationDepth*Z;
                 *  }
                 *
                 *  //Regenerate health (this is approx 1 sec)
                 *  if ((int) (Health + 0.0625) <= m_combatModule.MaximumHealth)
                 *      Health += 0.0625f;
                 *
                 *  if (Health > m_combatModule.MaximumHealth)
                 *      Health = m_combatModule.MaximumHealth;
                 * }
                 * if (Health <= 0)
                 * {
                 *  Die(killerObj);
                 * }*/
            }
Пример #14
0
        public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
                                    OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
        {
            bool ret = false;

            // The following lines make IsColliding(), CollidingGround() and CollidingObj work
            CollidingStep = PhysScene.SimulationStep;
            if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID)
            {
                CollidingGroundStep = PhysScene.SimulationStep;
            }
            else
            {
                CollidingObjectStep = PhysScene.SimulationStep;
            }

            CollisionAccumulation++;

            // For movement tests, remember if we are colliding with an object that is moving.
            ColliderIsMoving       = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
            ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;

            // Make a collection of the collisions that happened the last simulation tick.
            // This is different than the collection created for sending up to the simulator as it is cleared every tick.
            if (CollisionsLastTickStep != PhysScene.SimulationStep)
            {
                CollisionsLastTick     = new CollisionEventUpdate();
                CollisionsLastTickStep = PhysScene.SimulationStep;
            }
            CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));

            // If someone has subscribed for collision events log the collision so it will be reported up
            if (SubscribedEvents())
            {
                lock (PhysScene.CollisionLock)
                {
                    CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
                }
                DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
                          LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);

                ret = true;
            }
            return(ret);
        }
Пример #15
0
    protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
    {
        PhysicsScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        TypeName = typeName;

        Linkset = BSLinkset.Factory(PhysicsScene, this);
        LastAssetBuildFailed = false;

        // Default material type
        Material = MaterialAttributes.Material.Wood;

        CollisionCollection = new CollisionEventUpdate();
        SubscribedEventsMs = 0;
        CollidingStep = 0;
        CollidingGroundStep = 0;
    }
Пример #16
0
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            PhysicsScene   = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            TypeName       = typeName;

            Linkset = BSLinkset.Factory(PhysicsScene, this);
            LastAssetBuildFailed = false;

            // Default material type
            Material = MaterialAttributes.Material.Wood;

            CollisionCollection = new CollisionEventUpdate();
            SubscribedEventsMs  = 0;
            CollidingStep       = 0;
            CollidingGroundStep = 0;
        }
Пример #17
0
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            PhysicsScene   = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            Name           = name; // PhysicsActor also has the name of the object. Someday consolidate.
            TypeName       = typeName;

            // Oddity if object is destroyed and recreated very quickly it could still have the old body.
            if (!PhysBody.HasPhysicalBody)
            {
                PhysBody = new BulletBody(localID);
            }

            // The collection of things that push me around
            PhysicalActors = new BSActorCollection(PhysicsScene);

            // Initialize variables kept in base.
            GravityMultiplier = 1.0f;
            Gravity           = new OMV.Vector3(0f, 0f, BSParam.Gravity);

            PrimAssetState = PrimAssetCondition.Unknown;

            // Default material type. Also sets Friction, Restitution and Density.
            SetMaterial((int)MaterialAttributes.Material.Wood);

            CollisionCollection   = new CollisionEventUpdate();
            CollisionsLastTick    = CollisionCollection;
            SubscribedEventsMs    = 0;
            CollidingStep         = 0;
            TrueCollidingStep     = 0;
            CollisionAccumulation = 0;
            ColliderIsMoving      = false;
            CollisionScore        = 0;

            // All axis free.
            LockedLinearAxis  = LockedAxisFree;
            LockedAngularAxis = LockedAxisFree;
        }
Пример #18
0
    protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
    {
        PhysicsScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        TypeName = typeName;

        // We don't have any physical representation yet.
        PhysBody = new BulletBody(localID);
        PhysShape = new BulletShape();

        // A linkset of just me
        Linkset = BSLinkset.Factory(PhysicsScene, this);
        LastAssetBuildFailed = false;

        // Default material type
        Material = MaterialAttributes.Material.Wood;

        CollisionCollection = new CollisionEventUpdate();
        SubscribedEventsMs = 0;
        CollidingStep = 0;
        CollidingGroundStep = 0;
    }
Пример #19
0
        protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
        {
            PhysicsScene   = parentScene;
            LocalID        = localID;
            PhysObjectName = name;
            TypeName       = typeName;

            // We don't have any physical representation yet.
            PhysBody  = new BulletBody(localID);
            PhysShape = new BulletShape();

            // A linkset of just me
            Linkset = BSLinkset.Factory(PhysicsScene, this);
            LastAssetBuildFailed = false;

            // Default material type
            Material = MaterialAttributes.Material.Wood;

            CollisionCollection = new CollisionEventUpdate();
            SubscribedEventsMs  = 0;
            CollidingStep       = 0;
            CollidingGroundStep = 0;
        }
Пример #20
0
 public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
 {
     if (CollisionEventsThisFrame == null)
         CollisionEventsThisFrame = new CollisionEventUpdate();
     CollisionEventsThisFrame.addCollider(CollidedWith, contact);
 }
Пример #21
0
 public void SendCollisions()
 {
     if (m_eventsubscription >= m_requestedUpdateFrequency)
     {
         if (CollisionEventsThisFrame != null)
         {
             base.SendCollisionUpdate(CollisionEventsThisFrame);
         }
         CollisionEventsThisFrame = new CollisionEventUpdate();
         m_eventsubscription = 0;
     }
     return;
 }
Пример #22
0
 public override void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
 {
     if (CollisionEventsThisFrame == null)
         CollisionEventsThisFrame = new CollisionEventUpdate();
     lock (CollisionEventsThisFrame)
     {
         CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
         _parent_scene.AddCollisionEventReporting(this);
     }
 }
Пример #23
0
 private void HandleCollisionEnded(CollisionEventUpdate update)
 {
     this.HandleGenericCollisionEvent(update, Scenes.ScriptEvents.collision_end, m_parentGroup.Scene.EventManager.TriggerScriptCollidingEnd, false);
 }
Пример #24
0
 private void HandleLandCollisionBegan(CollisionEventUpdate update)
 {
     HandleGenericLandCollisionEvent(update, Scenes.ScriptEvents.land_collision_start,
         m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingStart, true);
 }
Пример #25
0
        private void HandleGenericCollisionEvent(CollisionEventUpdate update, Scenes.ScriptEvents eventType, EventManager.ScriptColliding callback,
            bool playSound)
        {
            // play the sound.
            if (playSound && CollisionSound != UUID.Zero && eventType == ScriptEvents.collision_start && CollisionSoundVolume > 0.0f)
            {
                SendSound(CollisionSound.ToString(), CollisionSoundVolume, true, (byte)0);
            }

            SceneObjectPart handlingPart = FindCollisionHandlingPart(eventType);
            if (handlingPart == null) return; //no one to handle the event

            ColliderArgs colliderArgs = new ColliderArgs();
            List<DetectedObject> colliding = new List<DetectedObject>();

            bool otherIsPrim;
            if (update.Type == CollisionEventUpdateType.CollisionBegan ||
                update.Type == CollisionEventUpdateType.CollisionContinues ||
                update.Type == CollisionEventUpdateType.BulkCollisionsContinue ||
                update.Type == CollisionEventUpdateType.CollisionEnded)
            {
                otherIsPrim = true;
            }
            else
            {
                otherIsPrim = false;
            }

            if (update.BulkCollisionData == null)
            {
                TryExtractCollider(update.OtherColliderLocalId, colliding, otherIsPrim, update.OtherColliderUUID);
            }
            else
            {
                foreach (uint localId in update.BulkCollisionData)
                {
                    TryExtractCollider(localId, colliding, otherIsPrim, update.OtherColliderUUID);
                }
            }
            

            if (colliding.Count > 0)
            {
                colliderArgs.Colliders = colliding;
                // always running this check because if the user deletes the object it would return a null reference.
                if (m_parentGroup == null)
                    return;
                if (m_parentGroup.Scene == null)
                    return;
                callback(handlingPart.LocalId, colliderArgs);
            }
        }
Пример #26
0
    protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
    {
        IsInitialized = false;

        PhysScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        Name = name;    // PhysicsActor also has the name of the object. Someday consolidate.
        TypeName = typeName;

        // The collection of things that push me around
        PhysicalActors = new BSActorCollection(PhysScene);

        // Initialize variables kept in base.
        GravModifier = 1.0f;
        Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
        HoverActive = false;

        // We don't have any physical representation yet.
        PhysBody = new BulletBody(localID);
        PhysShape = new BSShapeNull();

        UserSetCenterOfMassDisplacement = null;

        PrimAssetState = PrimAssetCondition.Unknown;

        // Default material type. Also sets Friction, Restitution and Density.
        SetMaterial((int)MaterialAttributes.Material.Wood);

        CollisionCollection = new CollisionEventUpdate();
        CollisionsLastReported = CollisionCollection;
        CollisionsLastTick = new CollisionEventUpdate();
        CollisionsLastTickStep = -1;

        SubscribedEventsMs = 0;
        // Crazy values that will never be true
        CollidingStep = BSScene.NotASimulationStep;
        CollidingGroundStep = BSScene.NotASimulationStep;
        CollisionAccumulation = BSScene.NotASimulationStep;
        ColliderIsMoving = false;
        CollisionScore = 0;

        // All axis free.
        LockedLinearAxis = LockedAxisFree;
        LockedAngularAxis = LockedAxisFree;
    }
Пример #27
0
    // I've collided with something
    public void Collide(uint collidingWith, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
    {
        // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);

        // The following lines make IsColliding() and IsCollidingGround() work
        _collidingStep = _scene.SimulationStep;
        if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
        {
            _collidingGroundStep = _scene.SimulationStep;
        }

        if (_subscribedEventsMs == 0) return;   // nothing in the object is waiting for collision events
        // throttle the collisions to the number of milliseconds specified in the subscription
        int nowTime = _scene.SimulationNowTime;
        if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
        _lastCollisionTime = nowTime;

        // create the event for the collision
        Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>();
        contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
        CollisionEventUpdate args = new CollisionEventUpdate(contactPoints);
        base.SendCollisionUpdate(args);
    }
Пример #28
0
 public override void SubscribeEvents(int ms)
 {
     m_eventsubscription = ms;
     m_cureventsubscription = 0;
     if (CollisionEventsThisFrame == null)
         CollisionEventsThisFrame = new CollisionEventUpdate();
     SentEmptyCollisionsEvent = false;
 }
Пример #29
0
    public virtual bool Collide(uint collidingWith, BSPhysObject collidee,
                    OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
    {
        bool ret = false;

        // The following lines make IsColliding(), CollidingGround() and CollidingObj work
        CollidingStep = PhysScene.SimulationStep;
        if (collidingWith <= PhysScene.TerrainManager.HighestTerrainID)
        {
            CollidingGroundStep = PhysScene.SimulationStep;
        }
        else
        {
            CollidingObjectStep = PhysScene.SimulationStep;
        }

        CollisionAccumulation++;

        // For movement tests, remember if we are colliding with an object that is moving.
        ColliderIsMoving = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero) : false;
        ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;

        // Make a collection of the collisions that happened the last simulation tick.
        // This is different than the collection created for sending up to the simulator as it is cleared every tick.
        if (CollisionsLastTickStep != PhysScene.SimulationStep)
        {
            CollisionsLastTick = new CollisionEventUpdate();
            CollisionsLastTickStep = PhysScene.SimulationStep;
        }
        CollisionsLastTick.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));

        // If someone has subscribed for collision events log the collision so it will be reported up
        if (SubscribedEvents()) {
            lock (PhysScene.CollisionLock)
            {
                CollisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
            }
            DetailLog("{0},{1}.Collison.AddCollider,call,with={2},point={3},normal={4},depth={5},colliderMoving={6}",
                            LocalID, TypeName, collidingWith, contactPoint, contactNormal, pentrationDepth, ColliderIsMoving);

            ret = true;
        }
        return ret;
    }
Пример #30
0
            public void PhysicsActor_OnCollisionUpdate(EventArgs e)
            {
                if (m_SP == null || m_SP.Invulnerable)
                {
                    return;
                }

                if (HasLeftCombat)
                {
                    return;
                }

                if (e == null)
                {
                    return;
                }

                CollisionEventUpdate            collisionData = (CollisionEventUpdate)e;
                Dictionary <uint, ContactPoint> coldata       = collisionData.m_objCollisionList;

                float starthealth = Health;
                uint  killerObj   = 0;

                foreach (uint localid in coldata.Keys)
                {
                    ISceneChildEntity part = m_SP.Scene.GetSceneObjectPart(localid);
                    if (part != null)
                    {
                        if (part.ParentEntity.Damage != -1.0f)
                        {
                            continue;
                        }
                        IScenePresence otherAvatar = m_SP.Scene.GetScenePresence(part.OwnerID);
                        if (otherAvatar != null) // If the avatar is null, the person is not inworld, and not on a team
                        {
                            if (otherAvatar.RequestModuleInterface <ICombatPresence>().HasLeftCombat)
                            {
                                //If they have left combat, do not let them cause any damage.
                                continue;
                            }
                        }
                        if (part.ParentEntity.Damage > MaximumDamageToInflict)
                        {
                            part.ParentEntity.Damage = MaximumDamageToInflict;
                        }

                        if (AllowTeams)
                        {
                            if (otherAvatar != null) // If the avatar is null, the person is not inworld, and not on a team
                            {
                                ICombatPresence OtherAvatarCP = otherAvatar.RequestModuleInterface <ICombatPresence>();
                                if (OtherAvatarCP.Team == Team)
                                {
                                    float Hits = 0;
                                    if (!TeamHits.TryGetValue(otherAvatar.UUID, out Hits))
                                    {
                                        Hits = 0;
                                    }
                                    Hits++;
                                    if (SendTeamKillerInfo && Hits == TeamHitsBeforeSend)
                                    {
                                        otherAvatar.ControllingClient.SendAlertMessage("You have shot too many teammates and " + DamageToTeamKillers + " health has been taken from you!");
                                        OtherAvatarCP.Health -= DamageToTeamKillers;
                                        otherAvatar.ControllingClient.SendHealth(OtherAvatarCP.Health);
                                        if (OtherAvatarCP.Health <= 0)
                                        {
                                            KillAvatar(otherAvatar.LocalId, true);
                                        }
                                        Hits = 0;
                                    }
                                    TeamHits[otherAvatar.UUID] = Hits;

                                    if (AllowTeamKilling) //Green light on team killing
                                    {
                                        Health -= part.ParentEntity.Damage;
                                    }
                                }
                                else //Object, hit em
                                {
                                    Health -= part.ParentEntity.Damage;
                                }
                            }
                            else //Other team, hit em
                            {
                                Health -= part.ParentEntity.Damage;
                            }
                        }
                        else //Free for all, hit em
                        {
                            Health -= part.ParentEntity.Damage;
                        }
                    }
                    else
                    {
                        float Z = m_SP.Velocity.Length() / 20;
                        if (coldata[localid].PenetrationDepth >= 0.05f && Math.Abs(m_SP.Velocity.X) < 1 && Math.Abs(m_SP.Velocity.Y) < 1)
                        {
                            Z = Math.Min(Z, 1.5f);
                            float damage = Math.Min(coldata[localid].PenetrationDepth, 15f);
                            Health -= damage * Z;
                        }
                    }

                    if (Health > m_combatModule.MaximumHealth)
                    {
                        Health = m_combatModule.MaximumHealth;
                    }

                    if (Health <= 0.0f)
                    {
                        if (localid != 0)
                        {
                            killerObj = localid;
                        }
                    }
                    //m_log.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString());
                }

                if (starthealth != Health)
                {
                    m_SP.ControllingClient.SendHealth(Health);
                }
                if (Health <= 0)
                {
                    KillAvatar(killerObj, true);
                }
            }
Пример #31
0
    // Routine to send the collected collisions into the simulator.
    // Also handles removal of this from the collection of objects with collisions if
    //      there are no collisions from this object. Mechanism is create one last
    //      collision event to make collision_end work.
    // Called at taint time from within the Step() function thus no locking problems
    //      with CollisionCollection and ObjectsWithNoMoreCollisions.
    // Return 'true' if there were some actual collisions passed up
    public virtual bool SendCollisions()
    {
        bool ret = true;

        // throttle the collisions to the number of milliseconds specified in the subscription
        int nowTime = PhysicsScene.SimulationNowTime;
        if (nowTime >= NextCollisionOkTime)
        {
            NextCollisionOkTime = nowTime + SubscribedEventsMs;

            // We are called if we previously had collisions. If there are no collisions
            //   this time, send up one last empty event so OpenSim can sense collision end.
            if (CollisionCollection.Count == 0)
            {
                // If I have no collisions this time, remove me from the list of objects with collisions.
                ret = false;
            }

            // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
            base.SendCollisionUpdate(CollisionCollection);

            // The collisionCollection structure is passed around in the simulator.
            // Make sure we don't have a handle to that one and that a new one is used for next time.
            CollisionCollection = new CollisionEventUpdate();
        }
        return ret;
    }
Пример #32
0
 public void SendCollisions()
 {
     if (m_eventsubscription > 0)
     {
         base.SendCollisionUpdate(CollisionEventsThisFrame);
         CollisionEventsThisFrame = new CollisionEventUpdate();
     }
 }
Пример #33
0
        public void SendCollisions()
        {
            if (CollisionEventsThisFrame == null)
                return;

            base.SendCollisionUpdate(CollisionEventsThisFrame);

            if (CollisionEventsThisFrame.m_objCollisionList.Count == 0)
                CollisionEventsThisFrame = null;
            else
                CollisionEventsThisFrame = new CollisionEventUpdate();
        }
Пример #34
0
    protected BSPhysObject(BSScene parentScene, uint localID, string name, string typeName)
    {
        PhysicsScene = parentScene;
        LocalID = localID;
        PhysObjectName = name;
        Name = name;    // PhysicsActor also has the name of the object. Someday consolidate.
        TypeName = typeName;

        // Initialize variables kept in base.
        GravModifier = 1.0f;
        Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);

        // We don't have any physical representation yet.
        PhysBody = new BulletBody(localID);
        PhysShape = new BulletShape();

        LastAssetBuildFailed = false;

        // Default material type. Also sets Friction, Restitution and Density.
        SetMaterial((int)MaterialAttributes.Material.Wood);

        CollisionCollection = new CollisionEventUpdate();
        CollisionsLastTick = CollisionCollection;
        SubscribedEventsMs = 0;
        CollidingStep = 0;
        CollidingGroundStep = 0;
        CollisionAccumulation = 0;
        ColliderIsMoving = false;
        CollisionScore = 0;

        // All axis free.
        LockedAxis = LockedAxisFree;
    }
Пример #35
0
 private void HandleLandCollisionEnded(CollisionEventUpdate update)
 {
     HandleGenericLandCollisionEvent(update, Scenes.ScriptEvents.land_collision_end,
         m_parentGroup.Scene.EventManager.TriggerScriptLandCollidingEnd, false);
 }
Пример #36
0
    // Send the collected collisions into the simulator.
    // Called at taint time from within the Step() function thus no locking problems
    //      with CollisionCollection and ObjectsWithNoMoreCollisions.
    // Return 'true' if there were some actual collisions passed up
    public virtual bool SendCollisions()
    {
        bool ret = true;
        // If the 'no collision' call, force it to happen right now so quick collision_end
        bool force = (CollisionCollection.Count == 0);

        // throttle the collisions to the number of milliseconds specified in the subscription
        if (force || (PhysicsScene.SimulationNowTime >= NextCollisionOkTime))
        {
            NextCollisionOkTime = PhysicsScene.SimulationNowTime + SubscribedEventsMs;

            // We are called if we previously had collisions. If there are no collisions
            //   this time, send up one last empty event so OpenSim can sense collision end.
            if (CollisionCollection.Count == 0)
            {
                // If I have no collisions this time, remove me from the list of objects with collisions.
                ret = false;
            }

            // DetailLog("{0},{1}.SendCollisionUpdate,call,numCollisions={2}", LocalID, TypeName, CollisionCollection.Count);
            base.SendCollisionUpdate(CollisionCollection);

            // The CollisionCollection instance is passed around in the simulator.
            // Make sure we don't have a handle to that one and that a new one is used for next time.
            //    This fixes an interesting 'gotcha'. If we call CollisionCollection.Clear() here, 
            //    a race condition is created for the other users of this instance.
            CollisionCollection = new CollisionEventUpdate();
        }
        return ret;
    }
Пример #37
0
        private void HandleGenericLandCollisionEvent(CollisionEventUpdate update, Scenes.ScriptEvents eventType,
            EventManager.ScriptLandColliding callback, bool playSound)
        {
            // play the sound.
            if (playSound && CollisionSound != UUID.Zero && eventType == ScriptEvents.collision_start && CollisionSoundVolume > 0.0f)
            {
                SendSound(CollisionSound, CollisionSoundVolume, (byte)SoundFlags.None, true);
            }

            SceneObjectPart handlingPart = FindCollisionHandlingPart(eventType);
            if (handlingPart == null) return; //no one to handle the event

            if (m_parentGroup == null)
                return;
            if (m_parentGroup.Scene == null)
                return;

            callback(handlingPart.LocalId, update.CollisionLocation);
        }
Пример #38
0
 public void AddCollisionEvent(uint CollidedWith, float depth)
 {
     if (CollisionEventsThisFrame == null)
         CollisionEventsThisFrame = new CollisionEventUpdate();
     CollisionEventsThisFrame.addCollider(CollidedWith,depth);
 }
Пример #39
0
 private void HandleCollisionBegan(CollisionEventUpdate update)
 {
     this.HandleGenericCollisionEvent(update, Scenes.ScriptEvents.collision_start, m_parentGroup.Scene.EventManager.TriggerScriptCollidingStart, true);
 }
Пример #40
0
        // The simulation step is telling this object about a collision.
        // I'm the 'collider', the thing I'm colliding with is the 'collidee'.
        // Return 'true' if a collision was processed and should be sent up.
        // Return 'false' if this object is not enabled/subscribed/appropriate for or has already seen this collision.
        // Called at taint time from within the Step() function
        public virtual bool Collide(BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
        {
            bool ret = false;

            // if 'collidee' is null, that means it is terrain
            uint collideeLocalID = (collidee == null) ? BSScene.TERRAIN_ID : collidee.LocalID;

            // All terrain goes by the TERRAIN_ID id when passed up as a collision
            if (collideeLocalID <= PhysScene.TerrainManager.HighestTerrainID)
            {
                collideeLocalID = BSScene.TERRAIN_ID;
            }

            // The following lines make IsColliding(), CollidingGround() and CollidingObj work
            CollidingStep = PhysScene.SimulationStep;
            if (collideeLocalID == BSScene.TERRAIN_ID)
            {
                CollidingGroundStep = PhysScene.SimulationStep;
            }
            else
            {
                CollidingObjectStep = PhysScene.SimulationStep;
            }

            CollisionAccumulation++;

            // For movement tests, if the collider is me, remember if we are colliding with an object that is moving.
            // Here the 'collider'/'collidee' thing gets messed up. In the larger context, when something is checking
            //     if the thing it is colliding with is moving, for instance, it asks if the its collider is moving.
            ColliderIsMoving       = collidee != null ? (collidee.RawVelocity != OMV.Vector3.Zero || collidee.RotationalVelocity != OMV.Vector3.Zero) : false;
            ColliderIsVolumeDetect = collidee != null ? (collidee.IsVolumeDetect) : false;


            // Make a collection of the collisions that happened the last simulation tick.
            // This is different than the collection created for sending up to the simulator as it is cleared every tick.
            if (CollisionsLastTickStep != PhysScene.SimulationStep)
            {
                CollisionsLastTick     = new CollisionEventUpdate();
                CollisionsLastTickStep = PhysScene.SimulationStep;
            }
            CollisionsLastTick.AddCollider(collideeLocalID, new ContactPoint(contactPoint, contactNormal, pentrationDepth));

            // If someone has subscribed for collision events log the collision so it will be reported up
            if (SubscribedEvents())
            {
                ContactPoint newContact = new ContactPoint(contactPoint, contactNormal, pentrationDepth);

                // Collision sound requires a velocity to know it should happen. This is a lot of computation for a little used feature.
                OMV.Vector3 relvel = OMV.Vector3.Zero;
                if (IsPhysical)
                {
                    relvel = RawVelocity;
                }
                if (collidee != null && collidee.IsPhysical)
                {
                    relvel -= collidee.RawVelocity;
                }
                newContact.RelativeSpeed = -OMV.Vector3.Dot(relvel, contactNormal);
                // DetailLog("{0},{1}.Collision.AddCollider,vel={2},contee.vel={3},relvel={4},relspeed={5}",
                //         LocalID, TypeName, RawVelocity, (collidee == null ? OMV.Vector3.Zero : collidee.RawVelocity), relvel, newContact.RelativeSpeed);

                lock (PhysScene.CollisionLock)
                {
                    CollisionCollection.AddCollider(collideeLocalID, newContact);
                }
                DetailLog("{0},{1}.Collision.AddCollider,call,with={2},point={3},normal={4},depth={5},speed={6},colliderMoving={7}",
                          LocalID, TypeName, collideeLocalID, contactPoint, contactNormal, pentrationDepth,
                          newContact.RelativeSpeed, ColliderIsMoving);

                ret = true;
            }
            return(ret);
        }
Пример #41
0
 private void HandleBulkCollisionsContinue(CollisionEventUpdate update)
 {
     HandleGenericCollisionEvent(update, Scenes.ScriptEvents.collision, m_parentGroup.Scene.EventManager.TriggerScriptColliding, false);
 }
Пример #42
0
 public override void AddCollisionEvent (uint CollidedWith, ContactPoint contact)
 {
     if (base.SubscribedToCollisions () && SubscribedEvents())//If we don't have anything that we are going to trigger, don't even add
     {
         if (CollisionEventsThisFrame == null)
             CollisionEventsThisFrame = new CollisionEventUpdate ();
         CollisionEventsThisFrame.addCollider (CollidedWith, contact);
     }
 }
Пример #43
0
 public void AddCollision(uint collideWith, ContactPoint contact)
 {
     if (CollisionEventsThisFrame == null)
     {
         CollisionEventsThisFrame = new CollisionEventUpdate();
     }
     CollisionEventsThisFrame.addCollider(collideWith, contact);
 }
Пример #44
0
 public override void SendCollisions ()
 {
     if (CollisionEventsThisFrame == null || m_frozen)//No collisions or frozen, don't mess with it
         return;
     base.SendCollisionUpdate (CollisionEventsThisFrame);
     if (CollisionEventsThisFrame.m_objCollisionList.Count == 0)
         CollisionEventsThisFrame = null;
     else
         CollisionEventsThisFrame = new CollisionEventUpdate ();
 }
Пример #45
0
        private void ReportContinuingCollisions()
        {
            if (_touchCounts.IsValueCreated && _touchCounts.Value.Count > 0)
            {
                List<uint> continuingList = new List<uint>(_touchCounts.Value.Count);
                foreach (PhysxPrim prim in _touchCounts.Value.Keys)
                {
                    if (this.GroupVelocity != OpenMetaverse.Vector3.Zero || prim._velocity != OpenMetaverse.Vector3.Zero)
                    {
                        continuingList.Add(prim._localId);
                    }
                }

                if (continuingList.Count > 0)
                {
                    CollisionEventUpdate upd = new CollisionEventUpdate { Type = CollisionEventUpdateType.BulkCollisionsContinue, BulkCollisionData = continuingList };
                    SendCollisionUpdate(upd);
                }
            }

            if (_groundTouchCounts > 0 && this.GroupVelocity != OpenMetaverse.Vector3.Zero)
            {
                OpenMetaverse.Vector3 currentLoc = DecomposeGroupPosition();

                SendCollisionUpdate(new CollisionEventUpdate { Type = CollisionEventUpdateType.LandCollisionContinues,
                    CollisionLocation = currentLoc});
            }

            if (_avatarTouchCounts.IsValueCreated && _avatarTouchCounts.Value.Count > 0)
            {
                List<uint> continuingList = new List<uint>(_avatarTouchCounts.Value.Count);
                foreach (PhysxCharacter avatar in _avatarTouchCounts.Value.Keys)
                {
                    continuingList.Add(avatar.LocalID);
                }

                if (continuingList.Count > 0)
                {
                    CollisionEventUpdate upd = new CollisionEventUpdate { Type = CollisionEventUpdateType.BulkAvatarCollisionsContinue, BulkCollisionData = continuingList };
                    SendCollisionUpdate(upd);
                }
            }
        }
Пример #46
0
 public override void UnSubscribeEvents()
 {
     if (CollisionEventsThisFrame != null)
     {
         lock (CollisionEventsThisFrame)
         {
             CollisionEventsThisFrame.Clear();
             CollisionEventsThisFrame = null;
         }
     }
     m_eventsubscription = 0;
 }
Пример #47
0
    public void Collide(uint collidingWith, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
    {
        // m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);

        // The following makes IsColliding() and IsCollidingGround() work
        _collidingStep = _scene.SimulationStep;
        if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
        {
            _collidingGroundStep = _scene.SimulationStep;
        }

        // throttle collisions to the rate specified in the subscription
        if (_subscribedEventsMs == 0) return;   // don't want collisions
        int nowTime = _scene.SimulationNowTime;
        if (nowTime < (_lastCollisionTime + _subscribedEventsMs)) return;
        _lastCollisionTime = nowTime;

        Dictionary<uint, ContactPoint> contactPoints = new Dictionary<uint, ContactPoint>();
        contactPoints.Add(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
        CollisionEventUpdate args = new CollisionEventUpdate(LocalID, (int)type, 1, contactPoints);
        base.SendCollisionUpdate(args);
    }
Пример #48
0
            public void PhysicsActor_OnCollisionUpdate(EventArgs e)
            {
                if (m_SP == null || m_SP.Scene == null || m_SP.Invulnerable || HasLeftCombat || e == null)
                {
                    return;
                }

                CollisionEventUpdate            collisionData = (CollisionEventUpdate)e;
                Dictionary <uint, ContactPoint> coldata       = collisionData.GetCollisionEvents();

                float          starthealth   = Health;
                IScenePresence killingAvatar = null;

                foreach (uint localid in coldata.Keys)
                {
                    ISceneChildEntity part        = m_SP.Scene.GetSceneObjectPart(localid);
                    IScenePresence    otherAvatar = null;
                    if (part != null && part.ParentEntity.Damage > 0)
                    {
                        otherAvatar = m_SP.Scene.GetScenePresence(part.OwnerID);
                        ICombatPresence OtherAvatarCP = otherAvatar == null
                                                            ? null
                                                            : otherAvatar.RequestModuleInterface <ICombatPresence> ();
                        if (OtherAvatarCP != null && OtherAvatarCP.HasLeftCombat)
                        {
                            // If the avatar is null, the person is not inworld, and not on a team
                            //If they have left combat, do not let them cause any damage.
                            continue;
                        }

                        //Check max damage to inflict
                        if (part.ParentEntity.Damage > m_combatModule.MaximumDamageToInflict)
                        {
                            part.ParentEntity.Damage = m_combatModule.MaximumDamageToInflict;
                        }

                        // If the avatar is null, the person is not inworld, and not on a team
                        if (m_combatModule.AllowTeams && OtherAvatarCP != null && otherAvatar.UUID != m_SP.UUID &&
                            OtherAvatarCP.Team == Team)
                        {
                            float Hits = 0;
                            if (!TeamHits.TryGetValue(otherAvatar.UUID, out Hits))
                            {
                                Hits = 0;
                            }
                            Hits++;
                            if (m_combatModule.SendTeamKillerInfo && Hits == m_combatModule.TeamHitsBeforeSend)
                            {
                                otherAvatar.ControllingClient.SendAlertMessage("You have shot too many teammates and " +
                                                                               m_combatModule.DamageToTeamKillers +
                                                                               " health has been taken from you!");
                                OtherAvatarCP.IncurDamage(null, m_combatModule.DamageToTeamKillers);
                                Hits = 0;
                            }
                            TeamHits [otherAvatar.UUID] = Hits;

                            if (m_combatModule.AllowTeamKilling) //Green light on team killing
                            {
                                Health -= part.ParentEntity.Damage;
                            }
                        }
                        else   //Object, hit em
                        {
                            Health -= part.ParentEntity.Damage;
                        }
                    }
                    else
                    {
                        float Z = m_SP.Velocity.Length();
                        if (coldata [localid].PenetrationDepth >= 0.05f && m_SP.Velocity.Z < -3 &&
                            !m_SP.PhysicsActor.Flying && !m_SP.PhysicsActor.IsJumping)
                        {
                            Z = Math.Max(Z, 1.5f) * 10;
                            float damage = Math.Min(coldata [localid].PenetrationDepth, 15f);
                            Health -= damage * Z;
                        }
                    }

                    if (Health > m_combatModule.MaximumHealth)
                    {
                        Health = m_combatModule.MaximumHealth;
                    }

                    if (Health <= 0 && killingAvatar == null)
                    {
                        killingAvatar = otherAvatar;
                    }
                    //MainConsole.Instance.Debug("[AVATAR]: Collision with localid: " + localid.ToString() + " at depth: " + coldata[localid].ToString());
                }

                if (starthealth != Health)
                {
                    m_SP.ControllingClient.SendHealth(Health);
                }

                if (Health <= 0)
                {
                    KillAvatar(killingAvatar, "You killed " + m_SP.Name, "You died!", true, true);
                }
            }