<commit_before>﻿/*
** Project ShiftDrive
** (C) <NAME>, 2016.
*/

using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ShiftDrive {
    
    internal enum ObjectType {
        Generic,
        Asteroid,
        Mine,
        Nebula,
        AIShip,
        PlayerShip,
        Station,
        BlackHole,
        Projectile
    }
    
    /// <summary>
    /// Represents a serializable object in the game world.
    /// </summary>
    internal abstract class GameObject {
        public uint id;
        public ObjectType type;

        public Vector2 position;
        public Vector2 velocity;
        public float facing;
        public byte sector;

        public string spritename;
        public SpriteSheet sprite;
        public Color color;

        public float bounding;

        public bool changed;

        private readonly lua_CFunction refLuaGet, refLuaSet;
        private bool destroyScheduled;
        private static uint nextId;

        protected GameObject() {
            id = ++nextId;
            refLuaGet = LuaGet;
            refLuaSet = LuaSet;
            changed = true;
            color = Color.White;
        }

        /// <summary>
        /// Updates this object.
        /// </summary>
        /// <param name="world">A reference to the <see cref="GameState"/> that this object is in.</param>
        /// <param name="deltaTime">The number of seconds that passed since the previous update.</param>
        public virtual void Update(GameState world, float deltaTime) {
            // handle collision with objects
            if (bounding > 0f) {
                foreach (GameObject obj in world.Objects.Values) {
                    if (obj.id == this.id)
                        continue; // don't collide with self
                    if (obj.bounding <= 0f)
                        continue; // don't collide with bounding-less objects

                    float dist = Vector2.DistanceSquared(obj.position, this.position);
                    if (dist > Math.Pow(obj.bounding + this.bounding, 2))
                        continue; // bounding sphere check

                    // calculate contact information
                    Vector2 normal = Vector2.Normalize(this.position - obj.position);
                    float penetration = this.bounding + obj.bounding - (float)Math.Sqrt(dist);
                    // handle collision response
                    OnCollision(obj, normal, penetration);
                }
            }

            // integrate velocity into position
            position += velocity * deltaTime;
            velocity *= (float)Math.Pow(0.8f, deltaTime);

            // animate the object sprite
            if (!world.IsServer) sprite.Update(deltaTime);

            // re-transmit object if it's moving around
            changed = changed || velocity.LengthSquared() > 0.01f;
        }
        
        /// <summary>
        /// Applies damage to this object. The derived class decides how
        /// damage affects the object, if at all.
        /// </summary>
        /// <param name="damage">The damage total to apply.</param>
        public virtual void TakeDamage(float damage) {
            // breakable objects should override this
        }

        /// <summary>
        /// Handle a collision with another <see cref="GameObject"/>.
        /// </summary>
        protected virtual void OnCollision(GameObject other, Vector2 normal, float penetration) {
            // apply minimum translation vector to resolve collision
            this.position += normal * penetration;
            this.velocity += normal * penetration;
        }

        /// <summary>
        /// Specifies whether this object counts as terrain.
        /// Terrain objects are only sent once to clients, saving bandwidth.
        /// </summary>
        public virtual bool IsTerrain() {
            return false;
        }

        /// <summary>
        /// Schedules this object for deletion. The server will erase the object
        /// once the update cycle has been completed.
        /// </summary>
        public virtual void Destroy() {
            destroyScheduled = true;
        }

        /// <summary>
        /// Returns a value indicating whether this object is scheduled for deletion.
        /// </summary>
        public bool ShouldDestroy() {
            return destroyScheduled;
        }

        /// <summary>
        /// Pushes a table to the Lua stack that represents this object.
        /// </summary>
        /// <param name="L">A pointer to the Lua state.</param>
        public void PushToLua(IntPtr L) {
            // push a dummy table with a metatable behind it
            LuaAPI.lua_createtable(L, 0, 0);
            LuaAPI.lua_createtable(L, 0, 2);
            LuaAPI.lua_pushcclosure(L, refLuaGet, 0);
            LuaAPI.lua_setfield(L, -2, "__index");
            LuaAPI.lua_pushcclosure(L, refLuaSet, 0);
            LuaAPI.lua_setfield(L, -2, "__newindex");<commit_msg>Add GameObject.IsShip()<commit_after>﻿/*
** Project ShiftDrive
** (C) <NAME>, 2016.
*/

using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace ShiftDrive {
    
    internal enum ObjectType {
        Generic,
        Asteroid,
        Mine,
        Nebula,
        AIShip,
        PlayerShip,
        Station,
        BlackHole,
        Projectile
    }
    
    /// <summary>
    /// Represents a serializable object in the game world.
    /// </summary>
    internal abstract class GameObject {
        public uint id;
        public ObjectType type;

        public Vector2 position;
        public Vector2 velocity;
        public float facing;
        public byte sector;

        public string spritename;
        public SpriteSheet sprite;
        public Color color;

        public float bounding;

        public bool changed;

        private readonly lua_CFunction refLuaGet, refLuaSet;
        private bool destroyScheduled;
        private static uint nextId;

        protected GameObject() {
            id = ++nextId;
            refLuaGet = LuaGet;
            refLuaSet = LuaSet;
            changed = true;
            color = Color.White;
        }

        /// <summary>
        /// Updates this object.
        /// </summary>
        /// <param name="world">A reference to the <see cref="GameState"/> that this object is in.</param>
        /// <param name="deltaTime">The number of seconds that passed since the previous update.</param>
        public virtual void Update(GameState world, float deltaTime) {
            // handle collision with objects
            if (bounding > 0f) {
                foreach (GameObject obj in world.Objects.Values) {
                    if (obj.id == this.id)
                        continue; // don't collide with self
                    if (obj.bounding <= 0f)
                        continue; // don't collide with bounding-less objects

                    float dist = Vector2.DistanceSquared(obj.position, this.position);
                    if (dist > Math.Pow(obj.bounding + this.bounding, 2))
                        continue; // bounding sphere check

                    // calculate contact information
                    Vector2 normal = Vector2.Normalize(this.position - obj.position);
                    float penetration = this.bounding + obj.bounding - (float)Math.Sqrt(dist);
                    // handle collision response
                    OnCollision(obj, normal, penetration);
                }
            }

            // integrate velocity into position
            position += velocity * deltaTime;
            velocity *= (float)Math.Pow(0.8f, deltaTime);

            // animate the object sprite
            if (!world.IsServer) sprite.Update(deltaTime);

            // re-transmit object if it's moving around
            changed = changed || velocity.LengthSquared() > 0.01f;
        }
        
        /// <summary>
        /// Applies damage to this object. The derived class decides how
        /// damage affects the object, if at all.
        /// </summary>
        /// <param name="damage">The damage total to apply.</param>
        public virtual void TakeDamage(float damage) {
            // breakable objects should override this
        }

        /// <summary>
        /// Handle a collision with another <see cref="GameObject"/>.
        /// </summary>
        protected virtual void OnCollision(GameObject other, Vector2 normal, float penetration) {
            // apply minimum translation vector to resolve collision
            this.position += normal * penetration;
            this.velocity += normal * penetration;
        }

        /// <summary>
        /// Specifies whether this object counts as terrain.
        /// Terrain objects are only sent once to clients, saving bandwidth.
        /// </summary>
        public virtual bool IsTerrain() {
            return false;
        }

        /// <summary>
        /// Schedules this object for deletion. The server will erase the object
        /// once the update cycle has been completed.
        /// </summary>
        public virtual void Destroy() {
            destroyScheduled = true;
        }

        /// <summary>
        /// Returns a value indicating whether this object is scheduled for deletion.
        /// </summary>
        public bool ShouldDestroy() {
            return destroyScheduled;
        }

        /// <summary>
        /// Returns true if this GameObject is a PlayerShip or AIShip.
        /// </summary>
        public bool IsShip() {
            return type == ObjectType.AIShip || type == ObjectType.PlayerShip;
        }

        /// <summary>
        /// Pushes a table to the Lua stack that represents this object.
        /// </summary>
        /// <param name="L">A pointer to the Lua state.</param>
        public void PushToLua(IntPtr L) {
            // push a dummy table with a metatable behind it
            LuaAPI.lua_createtable(L, 0, 0);
            LuaAPI.lua_createtable(L, 0, 2);
            LuaAPI.lua_pushcclosure(L, refLuaGet, 0);
            LuaAPI.lua_setfield(L, -2, "__index");
            LuaAPI.lua_pushcclosure(L, refLuaSet, 0);
            LuaAPI.lua_setfield(L, -2, "__newindex");
{'fraction_non_alphanumeric': 0.09597282872392043, 'fraction_numerical': 0.005046094129063561, 'mean_word_length': 1.6217247519715086, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2715935', 'n_tokens_mistral': 2673, 'n_tokens_neox': 2523, 'n_words': 834}