/// <summary>
        /// Fetch 4 direct neighbours
        /// </summary>
        /// <param name="field"></param>
        /// <returns></returns>
        public static List <Field> getDirectNeighbours(Field field)
        {
            List <Field> neigbouringFields = new List <Field>();

            int targetRegionId;
            int x = field.x - 1;
            int y = field.y;

            targetRegionId = GeometryIndex.calcRegionId(x, y);
            neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, y));

            x = field.x + 1;
            y = field.y;
            targetRegionId = GeometryIndex.calcRegionId(x, y);
            neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, y));

            x = field.x;
            y = field.y - 1;
            targetRegionId = GeometryIndex.calcRegionId(x, y);
            neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, y));

            x = field.x;
            y = field.y + 1;
            targetRegionId = GeometryIndex.calcRegionId(x, y);
            neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, y));

            return(neigbouringFields);
        }
示例#2
0
        public bool moveShipToField(Ship _ship, Field _targetField)
        {
            int   regionId    = GeometryIndex.calcRegionId(_ship.posX, _ship.posY);
            Field originField = GeometryIndex.regions[regionId].findOrCreateField(_ship.posX, _ship.posY);

            for (int i = 0; i < 10; i++)
            {
                bool originLocked = originField.setLock();
                bool targetLocked = _targetField.setLock();
                if (originLocked && targetLocked)
                {
                    originField.removeShip(_ship);
                    _targetField.AddShip(_ship);

                    originField.removeLock();
                    _targetField.removeLock();
                    return(true);
                }
                if (originLocked)
                {
                    originField.removeLock();
                }
                if (targetLocked)
                {
                    _targetField.removeLock();
                }
                Thread.Sleep(Lockable.rnd.Next(0, 50));
            }

            return(false);
        }
示例#3
0
        public void addStarToField(SystemMap _star)
        {
            int   regionId = GeometryIndex.calcRegionId(_star.posX, _star.posY);
            Field field    = GeometryIndex.regions[regionId].findOrCreateField(_star.posX, _star.posY);

            field.starId = _star.id;
            _star.field  = field;
        }
示例#4
0
        public bool addColonyToField(Colony _colony)
        {
            SystemMap colonyStar = stars[_colony.starId];
            int       regionId   = GeometryIndex.calcRegionId(colonyStar.posX, colonyStar.posY);
            Field     field      = GeometryIndex.regions[regionId].findOrCreateField(colonyStar.posX, colonyStar.posY);

            _colony.field = field;
            return(field.addColony(_colony));
        }
示例#5
0
        public void getAreaCreator(byte _direction, int _userId, Ship _ship, ref List <Ship> _ships, ref List <SpacegameServer.Core.SystemMap> _stars, ref List <SpacegameServer.Core.Colony> _colonies, Colony scanningColony = null)
        {
            var starXY = getDestinationField(_ship, _direction);

            if (_userId < 0)
            {
                return;
            }
            SpacegameServer.Core.User user = (SpacegameServer.Core.User)users[_userId];
            if (user == null)
            {
                return;
            }

            //fetch an area of radius 7 around the target field
            //check all colonies inside it. Every colony that has the targetfield inside it's border range is returned...
            //List<Field> neigbouringFields = new List<Field>();
            //GeometryIndex.getFields(_ship.field, 7, neigbouringFields);

            //int targetRegionId = GeometryIndex.calcRegionId(starXY.Key, starXY.Value);
            //var targetField = GeometryIndex.regions[targetRegionId].findOrCreateField(starXY.Key, starXY.Value);

            int targetRegionId = GeometryIndex.calcRegionId(starXY.Key, starXY.Value);
            var targetField    = GeometryIndex.regions[targetRegionId].findOrCreateField(starXY.Key, starXY.Value);

            //fetch all colonies affecting the targetField
            _colonies = Core.Instance.colonies.Where(colony => targetField.InfluencedBy.Any(influencer => influencer == colony.Value)).Select(colKeyValue => colKeyValue.Value).ToList();


            //fetch the star each colony is positioned
            foreach (int fieldId in (_colonies.Select(colony => colony.field.id)))
            {
                Field currentField = ((Field)GeometryIndex.allFields[fieldId]);

                if (currentField.starId != null)
                {
                    int       starId = (int)currentField.starId;
                    SystemMap star   = stars[starId];
                    _stars.Add(star);

                    //if scan is determined for a single ship, check if that user already kwos the systems scanned:
                    if ((_ship != null) && !user.knownStars.Contains(starId))
                    {
                        user.knownStars.Add(starId);
                        UserStarMap newStar = new UserStarMap(user.id, starId);

                        List <AsyncInsertable> newKnownStar = new List <AsyncInsertable>();
                        newKnownStar.Add(newStar);

                        dataConnection.insertAsyncTransaction(newKnownStar);
                    }
                }
            }

            return;
        }
示例#6
0
        public bool addShipToField(Ship _ship)
        {
            int   regionId = GeometryIndex.calcRegionId(_ship.posX, _ship.posY);
            Field field    = GeometryIndex.regions[regionId].findOrCreateField(_ship.posX, _ship.posY);

            SpacegameServer.Core.NodeQuadTree.Field shipField2 = new SpacegameServer.Core.NodeQuadTree.Field(_ship.posX, _ship.posY);
            nodeQuadTree.insertShip(shipField2, _ship);

            return(field.AddShip(_ship));
        }
        /*
         * a region consists of 10x10 fields
         * a field is always unique or null
         * */


        public static void createIndex()
        {
            int id = 0;

            for (int x = 0; x < GeometryIndex.regionsInRow; x++)
            {
                for (int y = 0; y < GeometryIndex.regionsInRow; y++)
                {
                    GeometryIndex.regions[id] = new Area(id, x, y);
                    id++;
                }
            }

            GeometryIndex.setNeighbours();
        }
        /// <summary>
        /// fetches a ring of fields aroung the destination
        /// </summary>
        /// <param name="field"></param>
        /// <param name="distance"></param>
        /// <param name="neigbouringFields"></param>
        public static void getNeighbourFields(Field field, int distance, List <Field> neigbouringFields, int overallRings)
        {
            int leftX   = field.x - distance;
            int upY     = field.y - distance;
            int rightX  = field.x + distance;
            int bottomY = field.y + distance;

            int targetRegionId;

            // Excluded corner fields are fields that are not used, starting from a corner in each direction
            // 1 means that only the corner is missing, 2 means that the corner and one field in each direction is missing
            // 3 means that thecorner and two fields in each direction are missing etc
            //var ExcludedCornerFields = Math.max(0, 2 * distance - overallRings - 1);
            // maximum number of excluded fields is distance - 1
            var ExcludedCornerFields = (distance - 1);

            // it is reduced by 1 for each additional ring around the colony after this ring:
            ExcludedCornerFields = ExcludedCornerFields - (overallRings - distance);
            ExcludedCornerFields = Math.Max(0, ExcludedCornerFields);


            //upper row and lower row
            for (var x = leftX + ExcludedCornerFields; x <= rightX - ExcludedCornerFields; x++)
            {
                targetRegionId = GeometryIndex.calcRegionId(x, upY);
                neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, upY));

                targetRegionId = GeometryIndex.calcRegionId(x, bottomY);
                neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, bottomY));
            }

            //left and right column (except top line and bottom line)
            var ExcludedY = Math.Max(1, ExcludedCornerFields);

            for (var y = upY + ExcludedY; y <= bottomY - ExcludedY; y++)
            {
                targetRegionId = GeometryIndex.calcRegionId(leftX, y);
                neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(leftX, y));

                targetRegionId = GeometryIndex.calcRegionId(rightX, y);
                neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(rightX, y));
            }
        }
        public static void getFields(Field field, int distance, List <Field> neigbouringFields)
        {
            int leftX   = field.x - distance;
            int upY     = field.y - distance;
            int rightX  = field.x + distance;
            int bottomY = field.y + distance;

            int targetRegionId;

            //upper row and lower row
            for (var x = leftX; x <= rightX; x++)
            {
                for (var y = upY; y <= bottomY; y++)
                {
                    targetRegionId = GeometryIndex.calcRegionId(x, y);
                    if (GeometryIndex.regions[targetRegionId].existsField(x, y))
                    {
                        neigbouringFields.Add(GeometryIndex.regions[targetRegionId].findOrCreateField(x, y));
                    }
                }
            }
        }
示例#10
0
        public Field nextFreeNonSystem()
        {
            int size = 20;

            int targetRegionId;

            //check all fields around the center
            for (short radius = 1; radius < size; radius++)
            {
                int left   = Math.Max((short)(this.x) - radius, 0);
                int right  = Math.Min((short)(this.x) + radius, size);
                int top    = Math.Max((short)(this.y) - radius, 0);
                int bottom = Math.Min((short)(this.y) + radius, size);

                for (int x = left; x < right; x++)
                {
                    //skip all fields inside the box
                    for (int y = top; y < bottom; y++)
                    {
                        if (left < x && x < right && top < y && y < bottom)
                        {
                            continue;
                        }

                        targetRegionId = GeometryIndex.calcRegionId(x, y);
                        if (GeometryIndex.regions[targetRegionId].existsField(x, y))
                        {
                            continue;
                        }

                        return(GeometryIndex.regions[targetRegionId].findOrCreateField(x, y));
                    }
                }
            }

            return(null);
        }
示例#11
0
        public static void applyInfluence(Field field, int influence, int userId, UserSpaceObject influenceCreator)
        {
            //number of rings aroung the field. 1 - 10?
            int rings = 1;

            rings = InfluenceManager.InfluenceToRingNo(influence);

            //find all neighbouring fields of the field
            //use the regions to accomplish this
            List <Field> neigbouringFields = new List <Field>();

            double factor = 1.0;

            for (int ring = rings; ring > 0; ring--)
            {
                //remove the influence that was needed to archieve this ring
                //var InfluenceOfThisRing = this.Influence - this.RingToMinInfluence(ring);
                var InfluenceOfThisRing = influence - InfluenceManager.RingToMinInfluence(ring);

                neigbouringFields.Clear();
                GeometryIndex.getNeighbourFields(field, ring, neigbouringFields, rings);

                //factor = 1.0d / Math.Pow(ring,2);
                //factor = 1.0d / (ring / 2.0d + ((ring - 1) * 4.0d));
                factor = 1.0 / ((ring * ring * ring) / 3.0);
                foreach (Field neighbour in neigbouringFields)
                {
                    neighbour.addInfluence(userId, (int)(InfluenceOfThisRing * factor), influenceCreator);
                }
                factor = factor * 1.3;
            }

            //the field where the colony is on
            factor = 100;
            field.addInfluence(userId, (int)(influence * factor), influenceCreator);
        }
示例#12
0
        //public SpaceGame.Game Socket;


        private Core(bool loadData = true, DataConnector connector = null)
        {
            if (connector == null)
            {
                dataConnection = new SpacegameServer.DataConnectors.SqlConnector();
            }
            else
            {
                dataConnection = connector;
            }

            writeToLog("Starting");

            InfluenceManager.InitInfluenceRings();

            identities.shipLock         = new IdentityNumbers();
            identities.templateLock     = new IdentityNumbers();
            identities.colonyId         = new IdentityNumbers();
            identities.colonyBuildingId = new IdentityNumbers();
            identities.planetSurfaceId  = new IdentityNumbers();
            identities.allianceId       = new IdentityNumbers();
            identities.commNode         = new IdentityNumbers();
            identities.commNodeMessage  = new IdentityNumbers();
            identities.message          = new IdentityNumbers();
            identities.combat           = new IdentityNumbers();
            identities.galacticEvents   = new IdentityNumbers();
            identities.trades           = new IdentityNumbers();
            identities.routes           = new IdentityNumbers();
            identities.chat             = new IdentityNumbers();

            //fill the regions array with (yet empty) regions
            //ToDo: this leads to a maximum siz of the world. Units should not leave the area...
            GeometryIndex.createIndex();



            //RULES
            //int ObjectDescriptionsSize = 20000;

            int GoodsSize         = 10000;
            int BuildingsSize     = 10000;
            int ModuleSize        = 5000;
            int SurfaceImagesSize = 50; //TODO
            int ShipHullsSize     = 230;
            //int ShipHullsImagesSize = 100;
            int QuestSize     = 1000;
            int ResearchsSize = 10000;

            //int SpecializationGroupSize = 10;

            int ResearchQuestPrerequisitesSize = 500;
            int SurfaceTilesSize = 30;

            int languageSize = 8;

            //MAP
            //int StarMapSize = 100000;
            //int SolarSystemInstanceSize = 1000000;
            //int PlanetSurfaceSize = 1000000;


            //USERS
            //int UserSize = 1000;
            //int ShipTemplateSize = UserSize * 1000;
            //int ShipSize = UserSize * 100;
            //int ColonySize = UserSize * 10;
            //int ColonyBuildingSize = ColonySize * 100;
            NodeQuadTree.BoundarySouthWest boundarySouthWest    = new NodeQuadTree.BoundarySouthWest(4096, 4096);
            NodeQuadTree.Bounding          NodeQuadTreeBounding = new NodeQuadTree.Bounding(boundarySouthWest, 2048);
            nodeQuadTree = new NodeQuadTree.NodeQuadTree(NodeQuadTreeBounding);

            //RULES
            ObjectDescriptions       = new Dictionary <int, ObjectDescription>(); //[ObjectDescriptionsSize];
            ObjectsOnMap             = new Dictionary <short, ObjectOnMap>();
            ObjectWeaponModificators = new Dictionary <short, Dictionary <short, ObjectWeaponModificator> >();

            Goods           = new Good[GoodsSize];
            Buildings       = new Building[BuildingsSize];
            PlanetTypes     = new List <PlanetType>(10);
            Modules         = new Module[ModuleSize];
            ShipHulls       = new ShipHull[ShipHullsSize];
            ShipHullsImages = new List <ShipHullsImage>();
            Quests          = new Quest[QuestSize];
            Researchs       = new Research[ResearchsSize];
            ResearchGains   = new List <ResearchGain>();

            SpecializationGroups = new List <SpecializationGroup>();

            ResearchQuestPrerequisites = new List <ResearchQuestPrerequisite>(ResearchQuestPrerequisitesSize);
            SurfaceImages      = new SurfaceImage[SurfaceImagesSize];
            SurfaceTiles       = new SurfaceTile[SurfaceTilesSize];
            BuildOptions       = new List <BuildOption>();
            objectRelations    = new List <ResearchQuestPrerequisite>(1000);
            surfaceDefaultMaps = new List <SurfaceDefaultMap>(3000);

            TurnEvaluations = new List <TurnEvaluation>(1000);

            languages = new Language[languageSize];
            //SurfaceImages = new SurfaceImages
            //MAP
            stars         = new Dictionary <int, SystemMap>();           // StarMap[StarMapSize];
            planets       = new Dictionary <int, SolarSystemInstance>(); //[SolarSystemInstanceSize];
            planetSurface = new Dictionary <long, PlanetSurface>();      // [PlanetSurfaceSize];

            //USERS
            users = new ConcurrentDictionary <int, User>();                     // [UserSize];

            shipTemplate    = new ConcurrentDictionary <int, ShipTemplate>();   // ShipTemplate[ShipTemplateSize];
            ships           = new ConcurrentDictionary <int, Ship>();           //Ship[ShipSize];
            colonies        = new ConcurrentDictionary <int, Colony>();         //Colony[ColonySize];
            colonyBuildings = new ConcurrentDictionary <int, ColonyBuilding>(); //ColonyBuilding[ColonyBuildingSize];

            alliances          = new ConcurrentDictionary <int, Alliance>();
            invitesPerAlliance = new ConcurrentDictionary <int, List <int> >();
            invitesPerUser     = new ConcurrentDictionary <int, List <int> >();

            tradeOffer = new ConcurrentDictionary <int, TradeOffer>();
            routes     = new ConcurrentDictionary <int, Route>();
            chatLog    = new ConcurrentDictionary <int, ChatLog>();

            userRelations = new UserRelations();

            labels     = new List <Label>();
            shipRefits = new List <shipRefit>();

            commNodes      = new ConcurrentDictionary <int, CommunicationNode>();
            messages       = new ConcurrentDictionary <int, MessageHead>();
            combats        = new ConcurrentDictionary <int, Combat>();
            galactivEvents = new ConcurrentDictionary <int, GalacticEvents>();

            //read all data
            if (loadData)
            {
                dataConnection.loadData(this);
            }

            /*
             * (new TurnSummary(this)).researchSpread(this); //Todo - remove, save to db after turn summary, restore from db when getAll(_core); is called
             * (new TurnSummary(this)).CalcGalaxyOwnership();
             *
             *
             * //update data in all ships
             * foreach (var ship in this.ships.Values)
             * {
             *  var clone = ship.clone();
             *  SpacegameServer.Core.StatisticsCalculator.calc(clone, this);
             *  ship.CombatMaxHitpoint = clone.hitpoints;
             *  ship.CombatStartHitpoint = ship.hitpoints;
             * }
             *
             *
             * //TODO
             * if (identities.shipLock.id == -1) identities.shipLock.id = 1000; //ToDo: F***ing ugly stupid and not even really functioning workaround, :ToDo : 1000 is a really bad workaround, because ships and colonies will sometimes (for example during trading) be stored in the same array as spaceobjects...
             *
             *
             * createTurnTimer();
             */
        }