コード例 #1
0
        public List <Ship> EnemiesOnField(int defenderUserId, Tuple <byte, byte> SysCoords)
        {
            var DefendingShips = this.ships.Where(ship => (ship.userid != defenderUserId &&
                                                           ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                            (SysCoords == null)) &&
                                                           UserRelations.IsLower(Core.Instance.userRelations.getRelation(defenderUserId, ship.userid), Relation.Neutral)));

            return(DefendingShips.ToList());
        }
コード例 #2
0
        /// <summary>
        /// Gets a bidirectional relation between user and target. Traverses recursively up, so that alliance relations are used
        /// </summary>
        /// <param name="user"></param>
        /// <param name="target"></param>
        /// <returns></returns>
        private FullDiplomaticRelationProposals getFullDiplomaticRelationProposals(DiplomaticEntity user, DiplomaticEntity target)
        {
            //fetch user parent data
            if (user.group != null)
            {
                FullDiplomaticRelationProposals proposal = getFullDiplomaticRelationProposals(user.group, target);
                proposal.sender = user;
                proposal.target = target;
                return(proposal);
            }

            //fetch target parent data
            if (target.group != null)
            {
                FullDiplomaticRelationProposals proposal = getFullDiplomaticRelationProposals(user, target.group);
                proposal.sender = user;
                proposal.target = target;
                return(proposal);
            }

            //no more parents left - fetch data
            Relation offer    = Relation.Neutral;
            Relation received = Relation.Neutral;
            Relation current  = Relation.Neutral;

            if (DiplomaticEntityState.ContainsKey(user) && DiplomaticEntityState[user].ContainsKey(target))
            {
                offer = DiplomaticEntityState[user][target];
            }

            if (DiplomaticEntityState.ContainsKey(target) && DiplomaticEntityState[target].ContainsKey(user))
            {
                received = DiplomaticEntityState[target][user];
            }

            if (target is User)
            {
                if (((User)target).AiId > 0 && ((User)target).AiRelation < (int)Relation.Neutral)
                {
                    received = UserRelations.Min(received, ((Relation)((User)target).AiRelation));
                }
            }

            current = Min(offer, received);

            FullDiplomaticRelationProposals fullDiplomatics = new FullDiplomaticRelationProposals(
                user,
                target,
                (int)offer,
                (int)received,
                (int)current
                );

            return(fullDiplomatics);
        }
コード例 #3
0
        public Ship detectAttackingShip(User Attacker, Tuple <byte, byte> SysCoords)
        {
            //var DefendingShips;
            //if (systemXY != null)
            //{
            //   DefendingShips

            CombatField CombatField = new SpacegameServer.Core.CombatField(this, SysCoords);

            var DefendingShips = this.ships.Where(ship => (ship.userid != Attacker.id &&
                                                           ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                            (SysCoords == null)) &&
                                                           UserRelations.IsLower(Core.Instance.userRelations.getRelation(Attacker.id, ship.userid), Relation.Neutral)));

            var AttackingShips = this.ships.Where(ship => ship.userid == Attacker.id &&
                                                  ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                   (SysCoords == null)));

            double BestRatio         = -1.0;
            Ship   BestAttackerSoFar = null;

            foreach (var PossibleAttacker in AttackingShips)
            {
                if (BestAttackerSoFar == null)
                {
                    BestAttackerSoFar = PossibleAttacker;
                }

                double bestDefender = Double.MaxValue;
                foreach (var Defender in DefendingShips)
                {
                    var ratio = Defender.AttackerDefenderRatio(PossibleAttacker, CombatField);
                    if (ratio < bestDefender)
                    {
                        bestDefender = ratio;
                    }
                }

                if (bestDefender > BestRatio)
                {
                    BestRatio         = bestDefender;
                    BestAttackerSoFar = PossibleAttacker;
                }
            }

            //}

            return(BestAttackerSoFar);
        }
コード例 #4
0
        //returns absolute relation (no proposals)
        public Relation getRelation(DiplomaticEntity user, DiplomaticEntity target)
        {
            Relation relation = Relation.Neutral;

            if (user == target)
            {
                return(Relation.AllianceMember);
            }

            try
            {
                if (user.group != null)
                {
                    return(getRelation(user.group, target));
                }
                if (target.group != null)
                {
                    return(getRelation(user, target.group));
                }



                Relation userTowardsTarget = DiplomaticEntityState.ContainsKey(user) &&
                                             DiplomaticEntityState[user].ContainsKey(target) ? DiplomaticEntityState[user][target] : Relation.Neutral;

                if (user is User)
                {
                    if (((User)user).AiId > 0 && ((User)user).AiRelation < (int)Relation.Neutral)
                    {
                        userTowardsTarget = UserRelations.Min(userTowardsTarget, ((Relation)((User)user).AiRelation));
                    }
                }

                Relation targetTowardsUser = DiplomaticEntityState.ContainsKey(target) &&
                                             DiplomaticEntityState[target].ContainsKey(user) ? DiplomaticEntityState[target][user] : Relation.Neutral;

                if (target is User)
                {
                    if (((User)target).AiId > 0 && ((User)target).AiRelation < (int)Relation.Neutral)
                    {
                        targetTowardsUser = UserRelations.Min(targetTowardsUser, ((Relation)((User)target).AiRelation));
                    }
                }

                relation = Min(userTowardsTarget, targetTowardsUser);
            }
            catch (Exception ex)
            {
                var userStr = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(user);
                SpacegameServer.Core.Core.Instance.writeToLog(userStr);

                var targetStr = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(user);
                SpacegameServer.Core.Core.Instance.writeToLog(targetStr);

                var DiplomaticEntityStateStr = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(DiplomaticEntityState);
                SpacegameServer.Core.Core.Instance.writeToLog(DiplomaticEntityStateStr);

                SpacegameServer.Core.Core.Instance.writeExceptionToLog(ex);
            }
            return(relation);
        }
コード例 #5
0
        /// <summary>
        /// set the relation between two entities
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="target"></param>
        /// <param name="relation"></param>
        /// <param name="relations">Is needed to write result to DB (and generate XML?) </param>
        /// <remarks>called with input data is already checked</remarks>
        protected void SetRelation(DiplomaticEntity sender, DiplomaticEntity target, Relation relation, List <DiplomaticRelation> relations)
        {
            Relation currentRelation = Relation.Neutral;

            if (DiplomaticEntityState.ContainsKey(sender) &&
                DiplomaticEntityState[sender].ContainsKey(target) &&
                DiplomaticEntityState.ContainsKey(target) &&
                DiplomaticEntityState[target].ContainsKey(sender))
            {
                currentRelation = Min(DiplomaticEntityState[sender][target], DiplomaticEntityState[target][sender]);
            }

            //worsening of the relation
            if (relation < currentRelation)
            {
                //Todo: lock all users, ships and alliances. Use a priority lock (to be implemented), since a lot of objects can be part of the transaction
                worsenRelation(sender, target, relation, relations);

                //always worth a Galactic Event
                GalacticEvents.CreateEventFromDiplomacy(sender, target, relation, currentRelation);

                return;
            }

            //relationion is not worsened:
            //either a proposal is done or
            // a proposal is accepted (and perhaps an additional proposal is done)

            //if targetRelationToSender is the currentRelation
            Relation targetRelationToSender = Relation.Neutral;

            if (DiplomaticEntityState.ContainsKey(target) &&
                DiplomaticEntityState[target].ContainsKey(sender))
            {
                targetRelationToSender = (Relation)DiplomaticEntityState[target][sender];
            }



            Relation newCurrentRelation = (Relation)Math.Min((int)targetRelationToSender, (int)relation);

            if (newCurrentRelation != currentRelation)
            {
                //change of relation: always worth a Galactic Event
                GalacticEvents.CreateEventFromDiplomacy(sender, target, newCurrentRelation, currentRelation);
            }

            //Some Relations can't be changed
            if (target is User)
            {
                if (((User)target).AiId > 0 && ((User)target).AiRelation < (int)Relation.Neutral)
                {
                    newCurrentRelation = UserRelations.Min(newCurrentRelation, ((Relation)((User)target).AiRelation));
                }
            }


            /*
             * //all senderusers should be set to newCurrentRelation
             * //create list of sender-Users
             * List<DiplomaticEntity> senders = sender.getMembers();
             *
             * //create list of target-Users
             * List<DiplomaticEntity> targets = target.getMembers();
             *
             * //update all users that are mebers and have a lower relationship than the new one:
             * foreach(var senderUser in senders)
             * {
             *  foreach(var targetUser in targets)
             *  {
             *      if (UserRelations.IsLower( getRelation(senderUser, targetUser) , newCurrentRelation))
             *      {
             *          setDiplomaticEntityState(senderUser, targetUser, newCurrentRelation);
             *          relations.Add(new DiplomaticRelation(senderUser.GetHashCode(), targetUser.GetHashCode(), (int)newCurrentRelation));
             *      }
             *      if (UserRelations.IsLower(getRelation(targetUser, senderUser) , newCurrentRelation))
             *      {
             *          setDiplomaticEntityState(targetUser, senderUser, newCurrentRelation);
             *          relations.Add(new DiplomaticRelation(targetUser.GetHashCode(), senderUser.GetHashCode(), (int)newCurrentRelation));
             *      }
             *  }
             * }
             *
             *
             * //and senderDiplomaticEntity proposes "his" relation
             * setDiplomaticEntityState(sender, target, relation);
             */

            foreach (var senderUser in sender.GetAllEntities())
            {
                foreach (var targetUser in target.GetAllEntities())
                {
                    setDiplomaticEntityState(senderUser, targetUser, relation);
                    relations.Add(new DiplomaticRelation(senderUser.GetHashCode(), targetUser.GetHashCode(), (int)relation));

                    /*
                     * if (UserRelations.IsLower(getRelation(senderUser, targetUser), newCurrentRelation))
                     * {
                     *  setDiplomaticEntityState(senderUser, targetUser, newCurrentRelation);
                     *  relations.Add(new DiplomaticRelation(senderUser.GetHashCode(), targetUser.GetHashCode(), (int)newCurrentRelation));
                     * }
                     * if (UserRelations.IsLower(getRelation(targetUser, senderUser), newCurrentRelation))
                     * {
                     *  setDiplomaticEntityState(targetUser, senderUser, newCurrentRelation);
                     *  relations.Add(new DiplomaticRelation(targetUser.GetHashCode(), senderUser.GetHashCode(), (int)newCurrentRelation));
                     * }
                     */
                }
            }
        }
コード例 #6
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();
             */
        }
コード例 #7
0
        public Ship StrongestEnemyOnField(Ship attackingShip, Tuple <byte, byte> SysCoords, int attackedShipId = 0)
        {
            CombatField CombatField = new SpacegameServer.Core.CombatField(this, SysCoords);

            var DefendingShips = this.ships.Where(ship => (ship.userid != attackingShip.userid &&
                                                           ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                                                            (SysCoords == null)) &&
                                                           UserRelations.IsLower(Core.Instance.userRelations.getRelation(attackingShip.userid, ship.userid), Relation.Neutral)));

            if (DefendingShips.Count() == 0 && attackedShipId != 0 && this.ships.Any(e => e.id == attackedShipId))
            {
                // the ship to attack is on the field. Add it to the DefendingShips, then add all other ships of this user or his alliance members, and all other ships from pact-members, as long as the pact is not also with the attacker
                var ShipToAttack    = this.ships.First(e => e.id == attackedShipId);
                var UserToAttack    = Core.Instance.users[ShipToAttack.userid];
                var UserThatAttacks = Core.Instance.users[attackingShip.userid];

                //Prepare Lists to get all other users that might defend the attcked ships
                var AttackerPacts = Core.Instance.userRelations.getAllContacts(UserThatAttacks, Relation.Pact);
                List <DiplomaticEntity> ExclusivePacts = new List <DiplomaticEntity>();
                List <User>             AllEnemyUsers  = new List <User>();

                if (UserToAttack.allianceId != 0 && UserThatAttacks.allianceId != UserToAttack.allianceId)
                {
                    AllEnemyUsers.AddRange(Core.Instance.alliances[UserToAttack.allianceId].getUsers());
                }
                else
                {
                    AllEnemyUsers.Add(UserToAttack);
                }

                //add pact-users that are not in a pact with the attacker
                foreach (var entry in Core.Instance.userRelations.getAllContacts(UserToAttack, Relation.Pact))
                {
                    if (AttackerPacts.Any(e => e.target == entry.target))
                    {
                        continue;
                    }

                    AllEnemyUsers.AddRange(entry.target.getUsers());
                }

                DefendingShips = this.ships.Where(
                    ship => AllEnemyUsers.Any(enemy => enemy.id == ship.userid) &&
                    ((SysCoords != null && ship.systemX == SysCoords.Item1 && ship.systemY == SysCoords.Item2) ||
                     (SysCoords == null))
                    );
            }

            //defensive pacts could provide additional defense unit at this point

            double BestRatio         = Double.MaxValue;
            Ship   BestDefenderSoFar = null;

            foreach (var Defender in DefendingShips)
            {
                if (BestDefenderSoFar == null)
                {
                    BestDefenderSoFar = Defender;
                }

                var ratio = Defender.AttackerDefenderRatio(attackingShip, CombatField);
                if (ratio < BestRatio)
                {
                    BestRatio         = ratio;
                    BestDefenderSoFar = Defender;
                }
            }

            return(BestDefenderSoFar);
        }