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()); }
/// <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); }
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); }
//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); }
/// <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)); * } */ } } }
//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(); */ }
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); }