Esempio n. 1
0
        //=========================================================================================
        /// <summary>
        /// Creates the projectile with the specified settings.
        /// </summary>
        /// <param name="owner">            Object that created the projectile.             </param>
        /// <param name="texture">          Texture to use for the projectile.              </param>
        /// <param name="spark_texture">    Spark texture to use for a projectile spark.    </param>
        /// <param name="effect">           Effect to render projectile with.               </param>
        /// <param name="position">         Intiial position of the projectile.             </param>
        /// <param name="live_time">        Amount of time the projectile has to live.      </param>
        /// <param name="velocity">         Initial velocity of the projectile.             </param>
        /// <param name="gravity">          Amount of gravity to apply to the projectile.   </param>
        /// <param name="size">             Size of the projectile.                         </param>
        /// <param name="damage">           Amount of damage this projectile does           </param>
        //=========================================================================================
        public EnemyProjectile( 
            GameObject  owner           , 
            Texture2D   texture         ,
            Texture2D   spark_texture   ,
            Effect      effect          ,
            Vector2     position        , 
            Vector2     velocity        ,
            float       live_time       ,
            float       gravity         ,
            float       size            ,
            float       damage      
        )
            : base(owner, texture, spark_texture , effect, position, velocity, live_time, gravity, size, damage)
        {
            // This projectile has not been deflected

            m_isDeflected = false;
        }
Esempio n. 2
0
        //=========================================================================================
        /// <summary> 
        /// Unregisters an object's type name with the scene. After this has finished the object will 
        /// no longer be found when searching for objects with this type name.
        /// </summary>
        /// 
        /// <param name="obj"> Object to unregister name for </param>
        //=========================================================================================
        private void UnregisterType( GameObject obj )
        {
            // Abort if null object:

            if ( obj == null ) return;

            // Do nothing if the object has no ID or is not in the scene:

            if ( obj.Id == 0 || obj.ParentContainer != this || obj.ParentLevel != this.m_level ) return;

            // Get the object's type name:

            string typeName = obj.GetType().Name;

            // Make sure the hash contains the type name

            if ( m_types.ContainsKey( typeName ) )
            {
                // Get the hash for this type name:

                Dictionary<int,GameObject> hash = m_types[typeName];

                // See if this object exists in the hash

                if ( hash.ContainsKey( obj.Id ) )
                {
                    // Bingo: remove the object from the hash

                    hash.Remove( obj.Id );

                    // If the hash is now empty then remove it from the parent hash

                    if ( hash.Count == 0 ){ m_types.Remove( typeName ); }
                }
            }
        }
Esempio n. 3
0
        //=========================================================================================
        /// <summary> 
        /// Registers an objects type name with the level data so the object can later be found by 
        /// using this type name. Multiple objects can be registered with the same type.
        /// </summary>
        /// 
        /// <param name="obj">Object to register type name for</param>
        //=========================================================================================
        private void RegisterType( GameObject obj )
        {
            // Abort if null object:

            if ( obj == null ) return;

            // Do nothing if the object has no ID or is not in the scene:

            if ( obj.Id == 0 || obj.ParentContainer != this || obj.ParentLevel != this.m_level ) return;

            // Get the object's type name:

            string typeName = obj.GetType().Name;

            // Create a hash for objects with this type if not already in existance

            if ( m_types.ContainsKey( typeName ) == false )
            {
                m_types.Add( typeName , new Dictionary<int,GameObject>() );
            }

            // Add the object into the hash:

            m_types[typeName][obj.Id] = obj;
        }
Esempio n. 4
0
        //=========================================================================================
        /// <summary>
        /// Applys damage to the character. Virtual so that derived classes can implement special 
        /// events for this action.
        /// </summary>
        /// <param name="amount">   Amount of damage to apply to the character.     </param>
        /// <param name="damager">  Thing that damaged the character. May be null.  </param>
        //=========================================================================================
        public override void Damage( float amount , GameObject damager )
        {
            // Call base function:

            base.Damage(amount,damager);

            // Good: now get the AI sight module

            AI_Sight b_sight = (AI_Sight) m_behaviours.GetBehaviour("AI_Sight");

            // If we have the sight module then suddenly jolt the player into visibilty: the ai should wake up after being hurt !!!

            if ( b_sight != null ) b_sight.AlertAI();
        }
Esempio n. 5
0
        //=====================================================================================
        /// <summary>
        /// Intersect query function. If an object is collideable it should also implement code to 
        /// do a line / line intersection test here. It should return all of the intersections 
        /// found.
        /// </summary>
        /// <param name="lineStart">        Start point of the line involved.               </param>
        /// <param name="lineEnd">          End point of the line involved.                 </param>
        /// <param name="otherObject">      Object making the collision query, may be null. </param>
        /// <param name="results">          Array to save the results to.                   </param>
        /// <param name="results_index">    Index in the array to save the results to.      </param>
        /// <returns>                       Number of results from the intersection test.   </returns>
        //=====================================================================================
        public override int OnIntersectQuery( 
            Vector2                 lineStart           ,
            Vector2                 lineEnd             ,
            GameObject              otherObject         ,      
            IntersectQueryResult[]  results             ,
            int                     results_index
        )
        {
            // Abort if no room to save new result:

            if ( results_index >= results.Length ) return 0;

            // Store the result here:

            Vector2 intersect_point = Vector2.Zero;

            // Do it:

            bool intersection = m_line.IntersectInfinite( new Line(lineStart,lineEnd) , ref intersect_point );

            // See if there was an intersection:

            if ( intersection )
            {
                // Make up the result:

                IntersectQueryResult result;

                result.ValidResult      = true;
                result.QueryObject      = this;
                result.Point            = intersect_point;
                result.Normal           = Vector2.UnitY;
                result.PointDistance    = Vector2.Distance(lineStart,intersect_point);

                // Save the result:

                results[results_index] = result;

                // Got a result: return 1

                return 1;
            }
            else
            {
                // No result:

                return 0;
            }
        }
Esempio n. 6
0
        //=========================================================================================
        /// <summary>
        /// Preforms an overlap query on the level for the given rectangle. 
        /// </summary>
        /// <param name="rectangle_position"> 
        /// Center of the bounding rectangle to check for overlap with </param>
        /// <param name="rectangle_dimensions">  
        /// Dimensions of the bounding rectangle to check for overlap with, in +/- x and y directions 
        /// from rectangle center.
        /// </param>
        /// <param name="caller"> 
        /// Object making the overlap query, may be null. 
        /// </param>
        //=========================================================================================
        public void Overlap( Vector2 rectangle_position , Vector2 rectangle_dimensions , GameObject caller )
        {
            // Reset number of overlaps that have occured:

            m_overlap_result_count = 0;

            // Get enumerator for the list of overlapable level objects:

            Dictionary<int,GameObject>.Enumerator e = m_level.Data.OverlapableObjects.GetEnumerator();

            // Run through the list of overlapable objects:

            while ( e.MoveNext() )
            {
                // If this object is the same as the caller then skip it:

                if ( caller == e.Current.Value ) continue;

                // Otherwise do an overlap test and save the result:

                OverlapQueryResult result = e.Current.Value.OnOverlapQuery
                (
                    rectangle_position      ,
                    rectangle_dimensions    ,
                    caller
                );

                // See if there was a result:

                if ( result.ValidResult )
                {
                    // Put into the overlaps list if not full already:

                    if ( m_overlap_result_count < MAX_RESULTS )
                    {
                        // On windows debug spit an error out if the object in the query is null:

                        #if WINDOWS_DEBUG

                            if ( result.QueryObject == null ) throw new NullReferenceException("Query result must have a valid query object !");

                        #endif

                        // Put into the list

                        m_overlap_results[m_overlap_result_count] = result;

                        // Increment the number of intersections:

                        m_overlap_result_count++;
                    }
                }
            }
        }
Esempio n. 7
0
        //=========================================================================================
        /// <summary>
        /// Preforms a collision query on the level for the given elipse. 
        /// </summary>
        /// <param name="ellipse_pos">   Center of the bounding elipse.                                              </param>
        /// <param name="ellipse_scale"> Dimensions of the elipse in +/- x and y directions from elipse center.      </param>
        /// <param name="ellipse_rot">   Amount the elipse is rotated by in radians.                                 </param>
        /// <param name="caller">        Object performing the query. This object will not be included in the test.  </param>
        //=========================================================================================
        public void Collide( Vector2 ellipse_pos , Vector2 ellipse_scale , float ellipse_rot , GameObject caller )
        {
            //-------------------------------------------------------------------------------------
            //-------------------------------------------------------------------------------------

            // Update the collision cache:

            {
                // Figure out how much the elipse must be scaled in the y direction to make it a circle

                float circlelizing_scale = ellipse_scale.X / ellipse_scale.Y;

                // Make the to ellipse local coordinate system transform matrix:

                CollisionCache.ToEllipseLocal =

                    Matrix.CreateTranslation( - ellipse_pos.X , - ellipse_pos.Y , 0 )
                    *
                    Matrix.CreateRotationZ( - ellipse_rot )
                    *
                    Matrix.CreateScale( 1 , circlelizing_scale , 1 );

                // Now make the opposite transform:

                CollisionCache.FromEllipseLocal =

                    Matrix.CreateScale( 1 , 1.0f / circlelizing_scale , 1 )
                    *
                    Matrix.CreateRotationZ( ellipse_rot )
                    *
                    Matrix.CreateTranslation( ellipse_pos.X , ellipse_pos.Y , 0 );

                // Rotate the four axis vectors of the ellipse:

                Vector2 v1 =   Vector2.UnitX * ellipse_scale.X;
                Vector2 v2 = - Vector2.UnitX * ellipse_scale.X;
                Vector2 v3 =   Vector2.UnitY * ellipse_scale.Y;
                Vector2 v4 = - Vector2.UnitY * ellipse_scale.Y;

                {
                    Matrix rot = Matrix.CreateRotationZ( ellipse_rot );

                    v1 = Vector2.Transform( v1 , rot );
                    v2 = Vector2.Transform( v2 , rot );
                    v3 = Vector2.Transform( v3 , rot );
                    v4 = Vector2.Transform( v4 , rot );
                }

                // Figure out the bounding box dimensions for the ellipse:

                CollisionCache.EllipseBoxTopLeft     = v1;
                CollisionCache.EllipseBoxBottomRight = v1;

                if ( v2.X < CollisionCache.EllipseBoxTopLeft.X ) CollisionCache.EllipseBoxTopLeft.X = v2.X;
                if ( v3.X < CollisionCache.EllipseBoxTopLeft.X ) CollisionCache.EllipseBoxTopLeft.X = v3.X;
                if ( v4.X < CollisionCache.EllipseBoxTopLeft.X ) CollisionCache.EllipseBoxTopLeft.X = v4.X;

                if ( v2.X > CollisionCache.EllipseBoxBottomRight.X ) CollisionCache.EllipseBoxBottomRight.X = v2.X;
                if ( v3.X > CollisionCache.EllipseBoxBottomRight.X ) CollisionCache.EllipseBoxBottomRight.X = v3.X;
                if ( v4.X > CollisionCache.EllipseBoxBottomRight.X ) CollisionCache.EllipseBoxBottomRight.X = v4.X;

                if ( v2.Y > CollisionCache.EllipseBoxTopLeft.Y ) CollisionCache.EllipseBoxTopLeft.Y = v2.Y;
                if ( v3.Y > CollisionCache.EllipseBoxTopLeft.Y ) CollisionCache.EllipseBoxTopLeft.Y = v3.Y;
                if ( v4.Y > CollisionCache.EllipseBoxTopLeft.Y ) CollisionCache.EllipseBoxTopLeft.Y = v4.Y;

                if ( v2.Y < CollisionCache.EllipseBoxBottomRight.Y ) CollisionCache.EllipseBoxBottomRight.Y = v2.Y;
                if ( v3.Y < CollisionCache.EllipseBoxBottomRight.Y ) CollisionCache.EllipseBoxBottomRight.Y = v3.Y;
                if ( v4.Y < CollisionCache.EllipseBoxBottomRight.Y ) CollisionCache.EllipseBoxBottomRight.Y = v4.Y;

                // Bring box points into world coords:

                CollisionCache.EllipseBoxTopLeft        += ellipse_pos;
                CollisionCache.EllipseBoxBottomRight    += ellipse_pos;

            }   // end of update collision cache

            //-------------------------------------------------------------------------------------
            //-------------------------------------------------------------------------------------

            // Reset number of collisions that have occured:

            m_collision_result_count = 0;

            // Get enumerator for the list of collideable level objects:

            Dictionary<int,GameObject>.Enumerator e = m_level.Data.CollideableObjects.GetEnumerator();

            // Run through the list of collideable objects:

            while ( e.MoveNext() )
            {
                // If this object is the same as the caller then skip it:

                if ( caller == e.Current.Value ) continue;

                // Otherwise do a collision test:

                int num_results = e.Current.Value.OnCollisionQuery
                (
                    ellipse_pos              ,
                    ellipse_scale            ,
                    ellipse_rot              ,
                    caller                   ,
                    m_collision_results      ,
                    m_collision_result_count
                );

                // Make sure number of results is positive:

                if ( num_results < 0 ) num_results = 0;

                // Increase number of collision results:

                m_collision_result_count += num_results;

                // Make sure in range:

                if ( m_collision_result_count > MAX_RESULTS ) m_collision_result_count = MAX_RESULTS;
            }
        }
Esempio n. 8
0
 //=========================================================================================
 /// <summary>
 /// Creates collision query result.
 /// </summary>
 /// <param name="validResult"> If this is a valid collision query result </param>
 /// <param name="queryObject"> Object involved in the collision query </param>
 /// <param name="point"> Point where the collision happened </param>
 /// <param name="normal"> Normal at the point of collision </param>
 /// <param name="penetration"> Amount of penetration into geometry by the elipse </param>
 /// <param name="resolveDirection"> Direction the elipse must move in to resolve collision </param>
 /// <param name="isPointCollision"> 
 /// Tells if the collision is a point collision. If so then the elipse has collided with a 
 /// point at the end of a line and not the line's plane itself.
 /// </param>
 //=========================================================================================
 public CollisionQueryResult(
     bool        validResult         ,
     GameObject  queryObject         ,
     Vector2     point               ,
     Vector2     normal              ,
     float       penetration         ,
     Vector2     resolveDirection    , 
     bool        isPointCollision    
 )
 {
     ValidResult         = validResult;
     QueryObject         = queryObject;
     Point               = point;
     Normal              = normal;
     Penetration         = penetration;
     ResolveDirection    = resolveDirection;
     IsPointCollision    = isPointCollision;
 }
Esempio n. 9
0
        //=====================================================================================
        /// <summary>
        /// Collision query function. If an object is collideable it should implement it's collision 
        /// testing code here and return the result of the collision. This collision test is for 
        /// a bounding elipse against a piece of geometry, such as a collection of lines etc. 
        /// </summary>
        /// <param name="elipsePosition">   Position of the bounding elipse                 </param>
        /// <param name="elipseDimensions"> Dimensions of the bounding elipse               </param>
        /// <param name="elipseRotation">   Amount the elipse is rotated by in radians.     </param>
        /// <param name="otherObject">      Object making the collision query, may be null. </param>
        /// <param name="results">          Array to save the results to.                   </param>
        /// <param name="results_index">    Index in the array to save the results to.      </param>
        /// <returns>                       Number of results from the collision.           </returns>
        //=====================================================================================
        public override int OnCollisionQuery( 
            Vector2                 elipsePosition      ,
            Vector2                 elipseDimensions    ,
            float                   elipseRotation      ,
            GameObject              otherObject         ,
            CollisionQueryResult[]  results             ,
            int                     results_index
        )
        {
            // If the index is past the end of the results array then do nothing:

            if ( results_index >= results.Length ) return 0;

            // Check out the collision cache and see if the ellipse is within bounds of our lines:

            if ( LevelCollisionQuery.CollisionCache.EllipseBoxTopLeft.X         > m_lines_bb_bottom_right.X ) return 0;
            if ( LevelCollisionQuery.CollisionCache.EllipseBoxBottomRight.X     < m_lines_bb_top_left.X     ) return 0;
            if ( LevelCollisionQuery.CollisionCache.EllipseBoxTopLeft.Y         < m_lines_bb_bottom_right.Y ) return 0;
            if ( LevelCollisionQuery.CollisionCache.EllipseBoxBottomRight.Y     > m_lines_bb_top_left.Y     ) return 0;

            // Store the number of results here:

            int num_results = 0;

            // Run through all the lines looking for a collision:

            for ( int i = 0 ; i < m_collision_lines.Length ; i++ )
            {
                // Store collision results here:

                Vector2 collide_point       = Vector2.Zero;
                Vector2 resolve_dir         = Vector2.Zero;
                Vector2 collide_normal      = Vector2.Zero;
                float   penetration         = 0;
                bool    point_collision     = false;

                // Test against this line:

                bool collision = m_collision_lines[i].FastCollide
                (
                    elipseDimensions.X                  ,
                    ref collide_point                   ,
                    ref resolve_dir                     ,
                    ref collide_normal                  ,
                    ref penetration                     ,
                    ref point_collision
                );

                // See if there was a collision

                if ( collision )
                {
                    // Increment number of results:

                    num_results++;

                    // Makeup the result:

                    CollisionQueryResult c;

                    c.ValidResult       = true;
                    c.QueryObject       = this;
                    c.Point             = collide_point;
                    c.Normal            = collide_normal;
                    c.Penetration       = penetration;
                    c.ResolveDirection  = resolve_dir;
                    c.IsPointCollision  = point_collision;

                    // Save the result:

                    results[results_index] = c;

                    // Increment results index:

                    results_index++;

                    // If past the end then return number of results:

                    if ( results_index >= results.Length ) return num_results;
                }

            }

            // Return the number of collision results

            return num_results;
        }
Esempio n. 10
0
        //=====================================================================================
        /// <summary>
        /// Intersect query function. If an object is collideable it should also implement code to 
        /// do a line / line intersection test here. It should return all of the intersections 
        /// found.
        /// </summary>
        /// <param name="lineStart">        Start point of the line involved.               </param>
        /// <param name="lineEnd">          End point of the line involved.                 </param>
        /// <param name="otherObject">      Object making the collision query, may be null. </param>
        /// <param name="results">          Array to save the results to.                   </param>
        /// <param name="results_index">    Index in the array to save the results to.      </param>
        /// <returns>                       Number of results from the intersection test.   </returns>
        //=====================================================================================
        public override int OnIntersectQuery( 
            Vector2                 lineStart           ,
            Vector2                 lineEnd             ,
            GameObject              otherObject         ,      
            IntersectQueryResult[]  results             ,
            int                     results_index
        )
        {
            // Abort if there is no more room for results:

            if ( results_index >= results.Length ) return 0;

            // Check out the collision cache and see if the ellipse is within bounds of our lines:

            if ( LevelCollisionQuery.IntersectionCache.RayBoxTopLeft.X      > m_lines_bb_bottom_right.X     ) return 0;
            if ( LevelCollisionQuery.IntersectionCache.RayBoxBottomRight.X  < m_lines_bb_top_left.X         ) return 0;
            if ( LevelCollisionQuery.IntersectionCache.RayBoxTopLeft.Y      < m_lines_bb_bottom_right.Y     ) return 0;
            if ( LevelCollisionQuery.IntersectionCache.RayBoxBottomRight.Y  > m_lines_bb_top_left.Y         ) return 0;

            // Store the number of results here:

            int num_results = 0;

            // Make a new line to test with:

            Line line = new Line( lineStart , lineEnd );

            // Collide the line with each of this object's lines:

            for ( int i = 0 ; i < m_collision_lines.Length ; i++ )
            {
                // Store the collision point here:

                Vector2 intersection_point = Vector2.Zero;

                // Do the intersection:

                bool lines_intersect = m_collision_lines[i].Intersect( line , ref intersection_point );

                // See if we got an intersection

                if ( lines_intersect )
                {
                    // Increment number of results:

                    num_results++;

                    // Get vector from line start to point of intersection

                    Vector2 r = intersection_point - lineStart;

                    // Get the distance to the point

                    float intersection_distance = Vector2.Dot( r , line.Direction );

                    // Make up the result:

                    IntersectQueryResult result;

                    result.ValidResult      = true;
                    result.QueryObject      = this;
                    result.Point            = intersection_point;
                    result.Normal           = m_collision_lines[i].Normal;
                    result.PointDistance    = intersection_distance;

                    // Save the result:

                    results[results_index] = result;

                    // Increment results index:

                    results_index++;

                    // If past the end then return number of results:

                    if ( results_index >= results.Length ) return num_results;
                }
            }

            // Return the number of collision results

            return num_results;
        }
Esempio n. 11
0
 //=========================================================================================
 /// <summary>
 /// Creates an intersect query result.
 /// </summary>
 /// <param name="validResult"> If this is a valid intersect query result </param>
 /// <param name="queryObject"> Object involved in the intersect query </param>
 /// <param name="point"> Point where the intersection happened </param>
 /// <param name="normal"> Normal at the point of intersection </param>
 /// <param name="pointDistance"> Distance from the start point of the ray cast the intersection point is </param>
 //=========================================================================================
 public IntersectQueryResult(
     bool        validResult             ,
     GameObject  queryObject             ,
     Vector2     point                   ,
     Vector2     normal                  ,
     float       pointDistance
 )
 {
     ValidResult     = validResult;
     QueryObject     = queryObject;
     Point           = point;
     Normal          = normal;
     PointDistance   = pointDistance;
 }
Esempio n. 12
0
        //=========================================================================================
        /// <summary>
        /// Adds the given amount to the player's score. Note that every time this is done, the 
        /// player's combat multiplier goes up in score.
        /// </summary>
        /// <param name="amount"> Amount to modify the player's score by. </param>
        /// <param name="caller"> Thing that is giving the score to the player. </param>
        //=========================================================================================
        public void GivePlayerScore( float amount , GameObject caller )
        {
            // If amount is negative then abort

            if ( amount <= 0 ) return;

            // Increase our score:

            m_player_score += amount * m_player_combat_multiplier;

            // Don't allow score to be negative:

            if ( m_player_score < 0 ) m_player_score = 0;

            // Try and find the floating scores object:

            FloatingScores scores = (FloatingScores) Core.Level.Search.FindByType("FloatingScores");

            // If found then make a new floating score at the position of the caller:

            if ( scores != null && caller != null )
            {
                // Make new score:

                 scores.AddScore( amount * m_player_combat_multiplier , caller.Position );
            }

            // Increase combat multiplier:

            m_player_combat_multiplier++;
        }
Esempio n. 13
0
        //=========================================================================================
        /// <summary>
        /// Applys damage to the character. Virtual so that derived classes can implement special 
        /// events for this action.
        /// </summary>
        /// <param name="amount">   Amount of damage to apply to the character.     </param>
        /// <param name="damager">  Thing that damaged the character. May be null.  </param>
        //=========================================================================================
        public override void Damage( float amount , GameObject damager )
        {
            // Call base function:

            base.Damage(amount,damager);

            // If we can do blood then do it:

            if ( m_time_to_blood <= 0 )
            {
                // Pick random time to next blood:

                float r = (float) Core.Random.NextDouble();

                // Pick time till next blood:

                m_time_to_blood = BLOOD_INTERVAL_1 * r + ( 1.0f - r ) * BLOOD_INTERVAL_2;

                // See if there was an object given:

                if ( damager != null )
                {
                    // Get direction to the object:

                    Vector2 dir = damager.Position - Position;

                    // Randomnly rotate the direction:

                    Matrix rot = Matrix.CreateRotationZ( 0.25f * (float) Core.Random.NextDouble() - 0.125f );

                    // Rotate direction randomnly:

                    dir = Vector2.Transform( dir , rot );

                    // First blood color to use:

                    Vector4 blood_color1 = Vector4.One;

                    blood_color1.X = 1.0f;
                    blood_color1.Y = 1.0f;
                    blood_color1.Z = 1.0f;
                    blood_color1.W = 0.35f;

                    // Second blood color to use:

                    Vector4 blood_color2 = Vector4.One;

                    blood_color2.X = 0.25f;
                    blood_color2.Y = 0.25f;
                    blood_color2.Z = 0.25f;
                    blood_color2.W = 0.65f;

                    // Spawn blood:

                    Core.Level.Emitter.CreateDirectedBurst
                    (
                        100                 ,
                        m_blood_texture     ,
                        Position            ,
                        dir                 ,
                        0.25f               ,
                        0.25f               ,
                        0.75f               ,
                        12.0f               ,
                        18.0f               ,
                        blood_color1        ,
                        blood_color2        ,
                        50                  ,
                        300                 ,
                        1000                ,
                        true
                    );

                }

            }
        }
Esempio n. 14
0
 //'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
 /// <summary>
 /// Constructor for the pending level change structure.
 /// </summary>
 /// <param name="o"> Object in question. </param>
 /// <param name="t"> Type of level change. </param>
 /// <param name="n"> Name of the object at type of change. For name changes only!</param>
 //'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
 public PendingLevelChange( GameObject o , PendingLevelChangeType t , string n )
 {
     obj = o; changeType = t; objectName = n;
 }
Esempio n. 15
0
        //=========================================================================================
        /// <summary>
        /// Applys damage to the character. Virtual so that derived classes can implement special 
        /// events for this action.
        /// </summary>
        /// <param name="amount">   Amount of damage to apply to the character.     </param>
        /// <param name="damager">  Thing that damaged the character. May be null.  </param>
        //=========================================================================================
        public override void Damage( float amount , GameObject damager )
        {
            // Do base class function

            base.Damage(amount,damager);

            // Reset our combat multiplier: find the game rules object first though

            LevelRules rules = (LevelRules) Core.Level.Search.FindByType("LevelRules");

            // See if there:

            if ( rules != null ) rules.ResetCombatMultplier();
        }
Esempio n. 16
0
 //=========================================================================================
 /// <summary>
 /// Creates an overlap query result.
 /// </summary>
 /// <param name="validResult"> If this is a valid overlap query result </param>
 /// <param name="queryObject"> Object involved in the overlap query </param>
 /// <param name="regionPosition"> Center of the region where the overlap occured </param>
 /// <param name="regionDimensions"> Dimensions of the overlap region in +/- x and y directions from region center </param>
 /// <param name="regionArea"> Area of the overlap region. </param>
 //=========================================================================================
 public OverlapQueryResult(
     bool        validResult         ,
     GameObject  queryObject         ,
     Vector2     regionPosition      ,
     Vector2     regionDimensions    ,
     float       regionArea
 )
 {
     ValidResult         = validResult;
     QueryObject         = queryObject;
     RegionPosition      = regionPosition;
     RegionDimensions    = regionDimensions;
     RegionArea          = regionArea;
 }
Esempio n. 17
0
        //=========================================================================================
        /// <summary> 
        /// Adds a given game object into the level data block.
        /// </summary>
        /// 
        /// <param name="obj"> GameObject to add </param>
        //=========================================================================================
        public void Add( GameObject obj )
        {
            // Make sure object not in another scene:

            if ( obj.Id != 0 || obj.ParentLevel != null || obj.ParentContainer != null ) return;

            // If the level data is locked then just add to the list of pending level data changes:

            if ( m_lock_count != 0 )
            {
                // Add this change to the list:

                m_pending_changes.AddLast
                (
                    new PendingLevelChange
                    (
                        obj                                 ,
                        PendingLevelChangeType.ADD_OBJECT   ,
                        obj.Name
                    )
                );

                // Abort: do not actually add the object into the list - we will do this later on Unlock()

                return;
            }

            // Choose an id for the object:

            int id = m_next_id;

                // If there are any free ids from deletion then use them: otherwise use the next free id and increment it

                if ( m_free_ids.Count > 0 )
                {
                    // Use the next free id gotten from deletion:

                    id = m_free_ids.First.Value; m_free_ids.RemoveFirst();
                }
                else
                {
                    // No id's ready from deletion: use the next free id and increment it

                    m_next_id++;
                }

            // Set ID, parent level and container:

            obj.Id              = id;
            obj.ParentLevel     = this.m_level;
            obj.ParentContainer = this;

            // Add to the appropriate dictionaries:

            m_objects.Add( obj.Id , obj );

            if ( obj.Renderable     ) m_renderables.Add     ( obj.Id , obj );
            if ( obj.Updateable     ) m_updateables.Add     ( obj.Id , obj );
            if ( obj.Collideable    ) m_collideables.Add    ( obj.Id , obj );
            if ( obj.Overlapable    ) m_overlapables.Add    ( obj.Id , obj );

            // Register the objects name and type for later quick lookup

            RegisterName(obj,obj.Name); RegisterType(obj);
        }
Esempio n. 18
0
        //=========================================================================================
        /// <summary>
        /// Creates the projectile with the specified settings.
        /// </summary>
        /// <param name="owner">            Object that created the projectile.             </param>
        /// <param name="texture">          Texture to use for the projectile.              </param>
        /// <param name="spark_texture">    Spark texture to use for a projectile spark.    </param>
        /// <param name="effect">           Effect to render projectile with.               </param>
        /// <param name="position">         Intiial position of the projectile.             </param>
        /// <param name="live_time">        Amount of time the projectile has to live.      </param>
        /// <param name="velocity">         Initial velocity of the projectile.             </param>
        /// <param name="gravity">          Amount of gravity to apply to the projectile.   </param>
        /// <param name="size">             Size of the projectile.                         </param>
        /// <param name="damage">           Amount of damage this projectile does           </param>
        //=========================================================================================
        public Projectile( 
            GameObject  owner           , 
            Texture2D   texture         ,
            Texture2D   spark_texture   ,
            Effect      effect          ,
            Vector2     position        , 
            Vector2     velocity        ,
            float       live_time       ,
            float       gravity         ,
            float       size            ,
            float       damage      
        )
            : base(false,true,false)
        {
            // Get the character type:

            m_character_type = Type.GetType("NinjaGame.Character");

            // Throw a wobbler in debug if not there:

            #if DEBUG

                if ( m_character_type == null ) throw new Exception("Code missing: no Character type got for projectile");

            #endif

            // Save all the stuff

            m_owner         = owner;
            Texture         = texture;
            m_spark_texture = spark_texture;
            Effect          = effect;
            Position        = position;
            m_velocity      = velocity;
            m_gravity       = gravity;
            m_live_time     = live_time;
            m_damage        = damage;

            // Set the size of the projectile:

            BoxDimensionsX = size;
            BoxDimensionsY = size;

            // Set default depth:

            Depth = 4500;
        }
Esempio n. 19
0
        //=========================================================================================
        /// <summary> 
        /// Registers an objects name with the scene so the object can later be found by using this 
        /// name. The name does not have to be unique and multiple objects could be retrieved under 
        /// the same name. 
        /// </summary>
        /// 
        /// <param name="obj"> Object to register name for </param>
        /// <param name="name"> Name to register the object under </param>
        //=========================================================================================
        public void RegisterName( GameObject obj , string name )
        {
            // Abort if null object:

            if ( obj == null ) return;

            // Do nothing if the object has no ID or is not in the scene:

            if ( obj.Id == 0 || obj.ParentContainer != this || obj.ParentLevel != this.m_level ) return;

            // Do nothing if no name was given:

            if ( name == null || name.Length <= 0 ) return;

            // If the level data is locked then just add to the list of pending level data changes:

            if ( m_lock_count != 0 )
            {
                // Add this change to the list:

                m_pending_changes.AddLast
                (
                    new PendingLevelChange
                    (
                        obj                                     ,
                        PendingLevelChangeType.REGISTER_NAME    ,
                        name
                    )
                );

                // Abort: do not actually add the object into the list - we will do this later on Unlock()

                return;
            }

            // Make the name lowercase:

            string nameLower = name.ToLower();

            // Create a hash for objects with this name if not already in existance

            if ( m_names.ContainsKey( nameLower ) == false )
            {
                m_names.Add( nameLower , new Dictionary<int,GameObject>() );
            }

            // Add the object into the hash:

            m_names[nameLower][obj.Id] = obj;
        }
Esempio n. 20
0
        //=========================================================================================
        /// <summary>
        /// Preforms a intersection query on the level for the given line. 
        /// </summary>
        /// <param name="line_start"> Start of the line </param>
        /// <param name="line_end"> End of the line </param>
        /// <param name="caller"> Object performing the query. This object will not be included in the test. </param>
        //=========================================================================================
        public void Intersect( Vector2 line_start , Vector2 line_end , GameObject caller )
        {
            //-------------------------------------------------------------------------------------
            //-------------------------------------------------------------------------------------

            // Update the intersection query cache:

            {
                // Figure out the bounds of the bounding box surrounding the ray:

                IntersectionCache.RayBoxTopLeft     = line_start;
                IntersectionCache.RayBoxBottomRight = line_start;

                if ( line_end.X < IntersectionCache.RayBoxTopLeft.X )
                {
                    IntersectionCache.RayBoxTopLeft.X = line_end.X;
                }

                if ( line_end.X > IntersectionCache.RayBoxBottomRight.X )
                {
                    IntersectionCache.RayBoxBottomRight.X = line_end.X;
                }

                if ( line_end.Y > IntersectionCache.RayBoxTopLeft.Y )
                {
                    IntersectionCache.RayBoxTopLeft.Y = line_end.Y;
                }

                if ( line_end.Y < IntersectionCache.RayBoxBottomRight.Y )
                {
                    IntersectionCache.RayBoxBottomRight.Y = line_end.Y;
                }

            }   // end of update collision cache

            //-------------------------------------------------------------------------------------
            //-------------------------------------------------------------------------------------

            // Reset number of intersections that have occured:

            m_intersect_result_count = 0;

            // Get enumerator for the list of collideable level objects:

            Dictionary<int,GameObject>.Enumerator e = m_level.Data.CollideableObjects.GetEnumerator();

            // Run through the list of collideable objects:

            while ( e.MoveNext() )
            {
                // If this object is the same as the caller then skip it:

                if ( caller == e.Current.Value ) continue;

                // Otherwise do an intersection test and save the number of results:

                int num_results = e.Current.Value.OnIntersectQuery
                (
                    line_start                  ,
                    line_end                    ,
                    caller                      ,
                    m_intersect_results         ,
                    m_intersect_result_count
                );

                // Make sure it is in range:

                if ( num_results < 0 ) num_results = 0;

                // Add to current intersect result count:

                m_intersect_result_count += num_results;

                // Clamp to within range:

                if ( m_intersect_result_count > MAX_RESULTS ) m_intersect_result_count = MAX_RESULTS;
            }
        }
Esempio n. 21
0
        //=========================================================================================
        /// <summary> 
        /// Removes the given GameObject from the level.
        /// </summary>
        /// 
        /// <param name="obj"> GameObject to remove</param>
        //=========================================================================================
        public void Remove( GameObject obj )
        {
            // Do nothing if objet is null:

            if ( obj == null ) return;

            // Do nothing if the object has no ID or is not in the scene:

            if ( obj.Id == 0 || obj.ParentContainer != this || obj.ParentLevel != this.m_level ) return;

            // See if object exists in scene:

            if ( m_objects.ContainsKey( obj.Id ) )
            {
                // If the level data is locked then just add to the list of pending level data changes:

                if ( m_lock_count != 0 )
                {
                    // Add this change to the list:

                    m_pending_changes.AddLast
                    (
                        new PendingLevelChange
                        (
                            obj                                     ,
                            PendingLevelChangeType.REMOVE_OBJECT    ,
                            obj.Name
                        )
                    );

                    // Abort: do not actually add the object into the list - we will do this later on Unlock()

                    return;
                }

                // Cleanup after the object:

                obj.OnDelete();

                // Unregister object name and type:

                UnregisterName(obj,obj.Name); UnregisterType(obj);

                // Remove object from all containers:

                m_objects.Remove( obj.Id );

                if ( m_renderables.ContainsKey(obj.Id)  ) m_renderables.Remove(obj.Id);
                if ( m_updateables.ContainsKey(obj.Id)  ) m_updateables.Remove(obj.Id);
                if ( m_collideables.ContainsKey(obj.Id) ) m_collideables.Remove(obj.Id);
                if ( m_overlapables.ContainsKey(obj.Id) ) m_overlapables.Remove(obj.Id);

                // Add this id to the list of free ids

                m_free_ids.AddLast(obj.Id);

                // Clear all the object's scene related variables

                obj.Id              = 0;
                obj.ParentLevel     = null;
                obj.ParentContainer = null;
            }
        }
Esempio n. 22
0
        //=====================================================================================
        /// <summary>
        /// Collision query function. If an object is collideable it should implement it's collision 
        /// testing code here and return the result of the collision. This collision test is for 
        /// a bounding elipse against a piece of geometry, such as a collection of lines etc. 
        /// </summary>
        /// <param name="elipsePosition">   Position of the bounding elipse                 </param>
        /// <param name="elipseDimensions"> Dimensions of the bounding elipse               </param>
        /// <param name="elipseRotation">   Amount the elipse is rotated by in radians.     </param>
        /// <param name="otherObject">      Object making the collision query, may be null. </param>
        /// <param name="results">          Array to save the results to.                   </param>
        /// <param name="results_index">    Index in the array to save the results to.      </param>
        /// <returns>                       Number of results from the collision.           </returns>
        //=====================================================================================
        public override int OnCollisionQuery( 
            Vector2                 elipsePosition      ,
            Vector2                 elipseDimensions    ,
            float                   elipseRotation      ,
            GameObject              otherObject         ,
            CollisionQueryResult[]  results             ,
            int                     results_index
        )
        {
            // Get height of the top texture (if any). the ground plane is at the bottom of this.

            int top_tex_height = 0;

            if ( m_top_texture != null ) top_tex_height = m_top_texture.Height;

            // Take two points along the ground surface:

            Vector2 ground_p1 = new Vector2( elipsePosition.X - 10 , PositionY + BoxDimensionsY - top_tex_height );
            Vector2 ground_p2 = new Vector2( elipsePosition.X + 10 , PositionY + BoxDimensionsY - top_tex_height );

            // Transform into the correct form so that the ellipse is a circle, it's rotations are undone and it's center is the center of the world

            ground_p1 = Vector2.Transform( ground_p1 , LevelCollisionQuery.CollisionCache.ToEllipseLocal );
            ground_p2 = Vector2.Transform( ground_p2 , LevelCollisionQuery.CollisionCache.ToEllipseLocal );

            /* OLD UNOPTIMIZED COLLISION CODE: WHICH IS MANUALLY DOING THESE TRANSFORMS

                // Get both relative to the center of the elipse:

                ground_p1 = ground_p1 - elipsePosition;
                ground_p2 = ground_p2 - elipsePosition;

                // Rotate them according to the elipse rotation: we are essentially rotating the world so the elipse is not rotated anymore

                Matrix rot = Matrix.CreateRotationZ( - elipseRotation );

                ground_p1 = Vector2.Transform( ground_p1 , rot );
                ground_p2 = Vector2.Transform( ground_p2 , rot );

                // Scale the worlds y coordinates so that the elipse becomes a circle:

                float world_y_scale = elipseDimensions.X / elipseDimensions.Y;

                ground_p1.Y *= world_y_scale;
                ground_p2.Y *= world_y_scale;

             @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */

            // Get the line normal:

            Vector2 ground_normal = new Vector2
            (
                - ( ground_p2.Y - ground_p1.Y  ) ,
                + ( ground_p2.X - ground_p1.X  )
            );

            ground_normal.Normalize();

            // Get distance to the ground:

            float distance = - Vector2.Dot( ground_p1 , ground_normal );

            // See if we are within range for a collision:

            if ( distance < elipseDimensions.X )
            {
                // Calculate penetration amount:

                float penetration = elipseDimensions.X - distance;

                // Calculate the collision point relative to the elipse center:

                Vector2 collision_point = - distance * ground_normal;

                // Calculate how much the elipse must move by to avoid collision:

                Vector2 resolve_vec = penetration * ground_normal;

                // Transform the collision point and resolve direction back into normal coordinates

                {
                    Vector4 v = Vector4.Zero;

                    v.X = resolve_vec.X;
                    v.Y = resolve_vec.Y;

                    v = Vector4.Transform( v , LevelCollisionQuery.CollisionCache.FromEllipseLocal );

                    resolve_vec.X = v.X;
                    resolve_vec.Y = v.Y;
                }

                collision_point = Vector2.Transform
                (
                    collision_point ,
                    LevelCollisionQuery.CollisionCache.FromEllipseLocal
                );

                /* OLD UNOPTIMIZED COLLISION CODE: WHICH IS MANUALLY DOING THESE TRANSFORMS

                // Now undo the previous scaling:

                resolve_vec.Y       /= world_y_scale;
                collision_point.Y   /= world_y_scale;

                // Undo the previous rotation:

                Matrix rot_inverse = Matrix.CreateRotationZ(elipseRotation);

                    resolve_vec     = Vector2.Transform(resolve_vec,rot_inverse);
                    collision_point = Vector2.Transform(collision_point,rot_inverse);

                // Make collision point back to world coordinates

                collision_point += elipsePosition;

                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ */

                // Get penetration amount

                penetration = resolve_vec.Length();

                // If the penetration is very small then abort:

                if ( penetration < 0.001f ) return 0;

                // Normalise resolve direction:

                resolve_vec /= penetration;

                // Save the result:

                if ( results_index < results.Length )
                {
                    // Make up the result:

                    CollisionQueryResult c;

                    c.ValidResult       = true;
                    c.QueryObject       = this;
                    c.Point             = collision_point;
                    c.Penetration       = penetration;
                    c.ResolveDirection  = resolve_vec;
                    c.Normal            = Vector2.UnitY;
                    c.IsPointCollision  = false;

                    // Save the result

                    results[results_index] = c;

                    // Got a valid result:

                    return 1;
                }
            }

            // If we got to here there was no result

            return 0;
        }
Esempio n. 23
0
        //=========================================================================================
        /// <summary> 
        /// Unregisters an object's name with the scene. After this has finished the object will 
        /// no longer be found when searching for objects with this name.
        /// </summary>
        /// 
        /// <param name="obj"> Object to unregister name for </param>
        /// <param name="name"> Name that the object is registered under </param>
        //=========================================================================================
        public void UnregisterName( GameObject obj , string name )
        {
            // Abort if null object:

            if ( obj == null ) return;

            // Do nothing if the object has no ID or is not in the scene:

            if ( obj.Id == 0 || obj.ParentContainer != this || obj.ParentLevel != this.m_level ) return;

            // Do nothing if no name was given:

            if ( name == null || name.Length <= 0 ) return;

            // If the level data is locked then just add to the list of pending level data changes:

            if ( m_lock_count != 0 )
            {
                // Add this change to the list:

                m_pending_changes.AddLast
                (
                    new PendingLevelChange
                    (
                        obj                                     ,
                        PendingLevelChangeType.UNREGISTER_NAME  ,
                        name
                    )
                );

                // Abort: do not actually add the object into the list - we will do this later on Unlock()

                return;
            }

            // Make the name lowercase:

            string nameLower = name.ToLower();

            // Make sure the hash contains the name

            if ( m_names.ContainsKey( nameLower ) )
            {
                // Get the hash for this name:

                Dictionary<int,GameObject> hash = m_names[nameLower];

                // See if this object exists in the hash

                if ( hash.ContainsKey( obj.Id ) )
                {
                    // Bingo: remove the object from the hash

                    hash.Remove( obj.Id );

                    // If the hash is now empty then remove it from the parent hash

                    if ( hash.Count == 0 ){ m_names.Remove( nameLower ); }
                }
            }
        }
Esempio n. 24
0
        //=========================================================================================
        /// <summary>
        /// Moves the camera towards an object so that it appears to follow the object.
        /// </summary>
        /// <param name="obj"> Object to follow </param>
        /// <param name="interpolateAmount">
        /// Amount that the camera should move over to the object's position by. If this is 1 then 
        /// the camera instantly assumes the position of the object. If this is 0 then the camera 
        /// never will assume the position of the object.
        /// </param>
        //=========================================================================================
        public void Follow( GameObject obj , float interpolateAmount )
        {
            // Clamp interpolate amount from 0-1

            if ( interpolateAmount < 0 ) interpolateAmount = 0;
            if ( interpolateAmount > 1 ) interpolateAmount = 1;

            // Make the camera follow the object:

            Position = Position * ( 1.0f - interpolateAmount ) + obj.Position * interpolateAmount;
        }
Esempio n. 25
0
        //=========================================================================================
        /// <summary>
        /// Applys damage to the character. Virtual so that derived classes can implement special 
        /// events for this action.
        /// </summary>
        /// <param name="amount">   Amount of damage to apply to the character.     </param>
        /// <param name="damager">  Thing that damaged the character. May be null.  </param>
        //=========================================================================================
        public virtual void Damage( float amount , GameObject damager )
        {
            // If the amount is nothing then do not bother:

            if ( amount <= 0 ) return;

            // Damage the character:

            m_health -= amount;

            // If health is less than zero: make zero

            if ( m_health < 0 ) m_health = 0;
        }