/// <summary> /// Processes functions involved in lodging a new ownership (and kingship) challenge /// Returns ProtoMessage in case of error /// </summary> public ProtoMessage LodgeOwnershipChallenge(PlayerCharacter challenger) { bool proceed = true; ProtoMessage result = null; // ensure aren't current owner if (challenger == this.owner) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.KingdomAlreadyKing; } else { // create and send new OwnershipChallenge OwnershipChallenge newChallenge = new OwnershipChallenge(Globals_Game.GetNextOwnChallengeID(), challenger.charID, "kingdom", this.id); proceed = Globals_Game.AddOwnershipChallenge(newChallenge, out result); } if (proceed) { // create and send journal entry // get interested parties PlayerCharacter currentOwner = this.owner; // ID uint entryID = Globals_Game.GetNextJournalEntryID(); // date uint year = Globals_Game.clock.currentYear; byte season = Globals_Game.clock.currentSeason; // location string entryLoc = this.id; // journal entry personae string allEntry = "all|all"; string currentOwnerEntry = currentOwner.charID + "|king"; string challengerEntry = challenger.charID + "|pretender"; string[] entryPersonae = new string[] { currentOwnerEntry, challengerEntry, allEntry }; // entry type string entryType = "depose_new"; // journal entry description string[] fields = new string[4]; fields[0] = this.name; fields[1] = this.id; fields[2] = challenger.firstName + " " + challenger.familyName; fields[3] = currentOwner.firstName + " " + currentOwner.familyName; ProtoMessage ownershipChallenge = new ProtoMessage(); ownershipChallenge.MessageFields = fields; ownershipChallenge.ResponseType = DisplayMessages.KingdomOwnershipChallenge; // create and send a proposal (journal entry) JournalEntry myEntry = new JournalEntry(entryID, year, season, entryPersonae, entryType, ownershipChallenge, loc: entryLoc); Globals_Game.AddPastEvent(myEntry); } return(result); }
/// <summary> /// Send an update to the client- used when the message to be sent requires additional information other than just a response code and some strings /// </summary> /// <param name="message">Message to be sent- can contain any number of details</param> public void Update(ProtoMessage message) { Contract.Requires(message != null); message.ActionType = Actions.Update; if (conn != null) { Globals_Server.logEvent("Update " + this.username + ": " + message.ResponseType.ToString()); //Server.SendViaProto(message, conn, alg); } }
/// <summary> /// Updates the client /// </summary> /// <param name="message">The message code to send</param> /// <param name="fields">Additional information to add to the message</param> public void Update(DisplayMessages message, string[] fields = null) { ProtoMessage m = new ProtoMessage(); m.ActionType = Actions.Update; m.ResponseType = message; m.MessageFields = fields; if (conn != null) { Globals_Server.logEvent("Update " + this.username + ": " + message.ToString()); //Server.SendViaProto(m, conn,alg); } }
/// <summary> /// Creates a JournalEntry for the attention of the game sysAdmin /// </summary> /// <returns>random double</returns> public static JournalEntry CreateSysAdminJentry() { JournalEntry jEntry = null; if (Globals_Game.sysAdmin != null) { // ID uint jEntryID = Globals_Game.GetNextJournalEntryID(); // date uint year = Globals_Game.clock.currentYear; byte season = Globals_Game.clock.currentSeason; // personae string sysAdminEntry = Globals_Game.sysAdmin.charID + "|sysAdmin"; string[] jEntryPersonae = new string[] { sysAdminEntry }; // create and send a proposal (journal entry) ProtoMessage errorMessage = new ProtoMessage(); jEntry = new JournalEntry(jEntryID, year, season, jEntryPersonae, "CSV_importError", errorMessage); } return(jEntry); }
public bool CheckName(string name) { return(ProtoMessage.CheckName(name, _index, 2 /* skip '{' and whitespace */, _protoAsText)); }
public bool CheckName(string name) { return(ProtoMessage.CheckName(name, _index, 1 /* skip colon */, _protoAsText)); }
/// <summary> /// Inserts the supplied PlayerCharacter's ID into the Position's officeHolder variable /// </summary> /// <param name="newPositionHolder">PlayerCharacter being assigned to the Position</param> public void BestowPosition(PlayerCharacter newPositionHolder) { PlayerCharacter oldPositionHolder = null; // remove existing holder if necessary if (!String.IsNullOrWhiteSpace(this.officeHolder)) { // get current holder if (Globals_Game.pcMasterList.ContainsKey(this.officeHolder)) { oldPositionHolder = Globals_Game.pcMasterList[this.officeHolder]; } // remove from position this.RemoveFromOffice(oldPositionHolder); } // assign position this.officeHolder = newPositionHolder.charID; // update stature newPositionHolder.AdjustStatureModifier(this.stature); // CREATE JOURNAL ENTRY // get interested parties bool success = true; PlayerCharacter king = this.GetKingdom().owner; // ID uint entryID = Globals_Game.GetNextJournalEntryID(); // date uint year = Globals_Game.clock.currentYear; byte season = Globals_Game.clock.currentSeason; // personae List <string> tempPersonae = new List <string>(); tempPersonae.Add("all|all"); tempPersonae.Add(king.charID + "|king"); tempPersonae.Add(newPositionHolder.charID + "|newPositionHolder"); if (oldPositionHolder != null) { tempPersonae.Add(oldPositionHolder.charID + "|oldPositionHolder"); } string[] thisPersonae = tempPersonae.ToArray(); // type string type = "grantPosition"; // description String[] fields = new string[] { this.title[0].name, king.firstName + " " + king.familyName, newPositionHolder.firstName + " " + newPositionHolder.familyName, "" }; if (oldPositionHolder != null) { fields[3] = "; This has necessitated the removal of " + oldPositionHolder.firstName + " " + oldPositionHolder.familyName + " from the position"; } ProtoMessage bestowPosition = new ProtoMessage(); bestowPosition.MessageFields = fields; bestowPosition.ResponseType = DisplayMessages.RankTitleTransfer; // create and add a journal entry to the pastEvents journal JournalEntry thisEntry = new JournalEntry(entryID, year, season, thisPersonae, type, bestowPosition); success = Globals_Game.AddPastEvent(thisEntry); }
/// <summary> /// Performs standard conditional checks before a pregnancy attempt /// </summary> /// <returns>bool indicating whether or not to proceed with pregnancy attempt</returns> /// <param name="husband">The husband</param> public static bool ChecksBeforePregnancyAttempt(Character husband, out ProtoMessage error) { error = null; bool proceed = true; bool isPlayer = husband is PlayerCharacter; bool isAncestorOfPlayer = (husband.GetHeadOfFamily()) is PlayerCharacter; if (!isPlayer && !isAncestorOfPlayer) { //TODO error log error = new ProtoMessage(); error.ResponseType = DisplayMessages.CharacterProposalFamily; error.MessageFields = new string[] { "husband" }; return(false); } // Must be male, as I discovered when William Marshal got pregnant. if (!husband.isMale) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.CharacterNotMale; return(false); } // Husband cannot be a captive if (!string.IsNullOrWhiteSpace(husband.captorID)) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.CharacterHeldCaptive; return(false); } // check is married // get spouse Character wife = husband.GetSpouse(); if (wife != null) { // Husband cannot be a captive if (!string.IsNullOrWhiteSpace(wife.captorID)) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.CharacterHeldCaptive; return(false); } // check to make sure is in same fief if (!(wife.location == husband.location)) { if (isPlayer) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.ErrorGenericNotInSameFief; } proceed = false; } else { // make sure wife not already pregnant if (wife.isPregnant) { if (isPlayer) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.BirthAlreadyPregnant; error.MessageFields = new string[] { wife.firstName + " " + wife.familyName }; } proceed = false; } // check if are kept apart by siege else { if ((!String.IsNullOrWhiteSpace(husband.location.siege)) && (husband.inKeep != wife.inKeep)) { if (isPlayer) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.BirthSiegeSeparation; } proceed = false; } else { // ensure player and spouse have at least 1 day remaining double minDays = Math.Min(husband.days, wife.days); if (minDays < 1) { error = new ProtoMessage(); error.ResponseType = DisplayMessages.ErrorGenericNotEnoughDays; proceed = false; } else { // ensure days are synchronised if (husband.days != wife.days) { if (husband.days != minDays) { if (husband is PlayerCharacter) { (husband as PlayerCharacter).AdjustDays(husband.days - minDays); } else { husband.AdjustDays(husband.days - minDays); } } else { wife.AdjustDays(wife.days - minDays); } } } } } } } // If the husband is a player, alert the husband's user // otherwise, the husband is the son of a player- alert the husband's father's user else { string whoThisIs = ""; if (isPlayer) { whoThisIs = "You are "; } else { whoThisIs = "This man is "; } error = new ProtoMessage(); error.ResponseType = DisplayMessages.BirthNotMarried; error.MessageFields = new string[] { whoThisIs }; proceed = false; } return(proceed); }
/// <summary> /// Allows an attacking army to lay siege to an enemy fief /// </summary> /// <param name="attacker">The attacking army</param> /// <param name="target">The fief to be besieged</param> public static Siege SiegeStart(Army attacker, Fief target) { Army defenderGarrison = null; Army defenderAdditional = null; // check for existence of army in keep for (int i = 0; i < target.armies.Count; i++) { // get army Army armyInFief = Globals_Game.armyMasterList[target.armies[i]]; // check is in keep Character armyLeader = armyInFief.GetLeader(); if (armyLeader != null) { if (armyLeader.inKeep) { // check owner is same as that of fief (i.e. can help in siege) if (armyInFief.GetOwner() == target.owner) { defenderAdditional = armyInFief; break; } } } } // create defending force defenderGarrison = target.CreateDefendingArmy(); // get the minumum days of all army objects involved double minDays = Math.Min(attacker.days, defenderGarrison.days); if (defenderAdditional != null) { minDays = Math.Min(minDays, defenderAdditional.days); } // get defenderAdditional ID, or null if no defenderAdditional string defAddID = null; if (defenderAdditional != null) { defAddID = defenderAdditional.armyID; } // create siege object Siege mySiege = new Siege(Globals_Game.GetNextSiegeID(), Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason, attacker.GetOwner().charID, target.owner.charID, attacker.armyID, defenderGarrison.armyID, target.id, minDays, target.keepLevel, defAdd: defAddID); // add to master list Globals_Game.siegeMasterList.Add(mySiege.siegeID, mySiege); // add to siege owners mySiege.GetBesiegingPlayer().mySieges.Add(mySiege.siegeID); mySiege.GetDefendingPlayer().mySieges.Add(mySiege.siegeID); // add to fief target.siege = mySiege.siegeID; // reduce expenditures in fief, except for garrison target.infrastructureSpendNext = 0; target.keepSpendNext = 0; target.officialsSpendNext = 0; // update days (NOTE: siege.days will be updated in syncDays) mySiege.totalDays++; // sychronise days mySiege.SyncSiegeDays(mySiege.days - 1); // =================== construct and send JOURNAL ENTRY // ID uint entryID = Globals_Game.GetNextJournalEntryID(); // personae List <string> tempPersonae = new List <string>(); tempPersonae.Add("all|all"); tempPersonae.Add(mySiege.GetDefendingPlayer().charID + "|fiefOwner"); tempPersonae.Add(mySiege.GetBesiegingPlayer().charID + "|attackerOwner"); tempPersonae.Add(attacker.GetLeader().charID + "|attackerLeader"); // get defenderLeader Character defenderLeader = defenderGarrison.GetLeader(); if (defenderLeader != null) { tempPersonae.Add(defenderLeader.charID + "|defenderGarrisonLeader"); } // get additional defending leader Character addDefendLeader = null; if (defenderAdditional != null) { addDefendLeader = defenderAdditional.GetLeader(); if (addDefendLeader != null) { tempPersonae.Add(addDefendLeader.charID + "|defenderAdditionalLeader"); } } string[] siegePersonae = tempPersonae.ToArray(); // location string siegeLocation = mySiege.GetFief().id; // description string[] fields = new string[6]; fields[0] = mySiege.GetBesiegingPlayer().firstName + " " + mySiege.GetBesiegingPlayer().familyName; fields[1] = attacker.GetLeader().firstName + " " + attacker.GetLeader().familyName; fields[2] = mySiege.GetFief().name; fields[3] = mySiege.GetDefendingPlayer().firstName + " " + mySiege.GetDefendingPlayer().familyName; fields[4] = fields[5] = ""; if (defenderLeader != null) { fields[4] = "The defending garrison is led by " + defenderLeader.firstName + " " + defenderLeader.familyName + "."; } if (addDefendLeader != null) { fields[5] = "Additional defending forces are led by " + addDefendLeader.firstName + " " + addDefendLeader.familyName + "."; } ProtoMessage siege = new ProtoMessage(); siege.MessageFields = fields; siege.ResponseType = DisplayMessages.PillageInitiateSiege; // put together new journal entry JournalEntry siegeResult = new JournalEntry(entryID, Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason, siegePersonae, "siege", siege, loc: siegeLocation); // add new journal entry to pastEvents Globals_Game.AddPastEvent(siegeResult); return(mySiege); }
/// <summary> /// Implements conditional checks prior to the pillage or siege of a fief /// </summary> /// <returns>bool indicating whether pillage/siege can proceed</returns> /// <param name="f">The fief being pillaged/besieged</param> /// <param name="a">The pillaging/besieging army</param> /// <param name="circumstance">The circumstance - pillage or siege</param> public static bool ChecksBeforePillageSiege(Army a, Fief f, out ProtoMessage result, string circumstance = "pillage") { result = null; bool proceed = true; string operation = ""; // check if is your own fief // note: not necessary for quell rebellion if (!circumstance.Equals("quellRebellion")) { if (f.owner == a.GetOwner()) { proceed = false; if (circumstance.Equals("pillage")) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageOwnFief; result.MessageFields = new string[] { "pillage" }; } else if (circumstance.Equals("siege")) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageOwnFief; result.MessageFields = new string[] { "siege" }; } } else if (a.GetOwner().isAlly(f.owner)) { proceed = false; if (circumstance.Equals("pillage")) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageAllyFief; result.MessageFields = new string[] { "pillage" }; } else if (circumstance.Equals("siege")) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageAllyFief; result.MessageFields = new string[] { "siege" }; } } } // check if fief is under siege // note: not necessary for quell rebellion if (!circumstance.Equals("quellRebellion")) { if ((!String.IsNullOrWhiteSpace(f.siege)) && (proceed)) { proceed = false; if (circumstance.Equals("pillage")) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageUnderSiege; } else if (circumstance.Equals("siege")) { result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageSiegeAlready; } } } // check if fief already pillaged // note: not necessary for quell rebellion (get a 'free' pillage) if (!circumstance.Equals("quellRebellion")) { if (circumstance.Equals("pillage")) { // check isPillaged = false if ((f.isPillaged) && (proceed)) { proceed = false; result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageAlready; } } } // check if your army has a leader if (a.GetLeader() == null) { proceed = false; if (circumstance.Equals("quellRebellion")) { operation = "Operation"; } if (circumstance.Equals("pillage")) { operation = "Pillage"; } else if (circumstance.Equals("siege")) { operation = "Siege"; } result = new ProtoMessage(); result.ResponseType = DisplayMessages.ArmyNoLeader; } // check has min days required if ((circumstance.Equals("pillage")) || (circumstance.Equals("quellRebellion"))) { // pillage = min 7 if ((a.days < 7) && (proceed)) { proceed = false; if (circumstance.Equals("quellRebellion")) { operation = "Quell rebellion"; } else { operation = "Pillage"; } result = new ProtoMessage(); result.ResponseType = DisplayMessages.ErrorGenericNotEnoughDays; } } else if (circumstance.Equals("siege")) { // siege = 1 (to set up siege) if ((a.days < 1) && (proceed)) { proceed = false; result = new ProtoMessage(); result.ResponseType = DisplayMessages.ErrorGenericNotEnoughDays; } } // check for presence of armies belonging to fief owner if (proceed) { // iterate through armies in fief for (int i = 0; i < f.armies.Count; i++) { // get army Army armyInFief = Globals_Game.armyMasterList[f.armies[i]]; // check if owned by fief owner if (armyInFief.owner.Equals(f.owner.charID)) { // army must be outside keep if (!armyInFief.GetLeader().inKeep) { // army must have correct aggression settings if (armyInFief.aggression > 1) { proceed = false; if (circumstance.Equals("pillage")) { operation = "Pillage"; } else if (circumstance.Equals("siege")) { operation = "Siege"; } else if (circumstance.Equals("quellRebellion")) { operation = "Quell rebellion"; } result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageArmyDefeat; result.MessageFields = new string[] { armyInFief.armyID }; break; } } } } // check if fief in rebellion if ((circumstance.Equals("siege")) && (proceed)) { if (f.status.Equals('R')) { proceed = false; result = new ProtoMessage(); result.ResponseType = DisplayMessages.PillageSiegeRebellion; } } } return(proceed); }
/// <summary> /// Implements the processes involved in the pillage of a fief by an army /// </summary> /// <param name="a">The pillaging army</param> /// <param name="f">The fief being pillaged</param> public static ProtoMessage PillageFief(Army a, Fief f) { ProtoMessage result = new ProtoMessage(); bool pillageCancelled = false; bool bailiffPresent = false; Army fiefArmy = null; // check if bailiff present in fief (he'll lead the army) if (f.bailiff != null) { for (int i = 0; i < f.charactersInFief.Count; i++) { if (f.charactersInFief[i] == f.bailiff) { bailiffPresent = true; break; } } } // if bailiff is present, create an army and attempt to give battle // no bailiff = no leader = pillage is unopposed by defending forces if (bailiffPresent) { // create temporary army for battle fiefArmy = f.CreateDefendingArmy(); // give battle and get result ProtoBattle battleResults; pillageCancelled = Battle.GiveBattle(fiefArmy, a, out battleResults, circumstance: "pillage"); if (pillageCancelled) { string toDisplay = "The pillaging force has been forced to retreat by the fief's defenders!"; result.ResponseType = DisplayMessages.PillageRetreat; // Let owner know that pillage attempt has been thwarted Globals_Game.UpdatePlayer(f.owner.playerID, DisplayMessages.PillageRetreat); return(result); } else { // check still have enough days left if (a.days < 7) { // Inform fief owner pillage attempt thwarted Globals_Game.UpdatePlayer(f.owner.playerID, DisplayMessages.PillageDays); result.ResponseType = DisplayMessages.PillageDays; pillageCancelled = true; return(result); } } } if (!pillageCancelled) { // process pillage return(Pillage_Siege.ProcessPillage(f, a)); } result.ResponseType = DisplayMessages.Success; result.Message = "The pillage was successful"; return(result); }