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