public static void BuyTitle(string sessionId) { using (var db = new FiefContext()) { Fief fiefdom = db.Fiefdom.Where(f => f.SessionId == sessionId).Include("FiefdomPlot").Include("FiefdomResources").FirstOrDefault(); var gold = fiefdom.FiefdomResources.Where(x => x.Type == "Gold").FirstOrDefault(); switch (fiefdom.Title) { case 0: if (gold.Quantity >= 1000) { fiefdom.Title = 1; gold.Quantity -= 1000; UnlockPlot(fiefdom); UnlockPlot(fiefdom); } break; case 1: if (gold.Quantity >= 5000) { fiefdom.Title = 2; gold.Quantity -= 5000; UnlockPlot(fiefdom); UnlockPlot(fiefdom); } break; case 2: if (gold.Quantity >= 10000) { fiefdom.Title = 3; gold.Quantity -= 10000; UnlockPlot(fiefdom); UnlockPlot(fiefdom); } break; case 3: if (gold.Quantity >= 20000) { fiefdom.Title = 4; gold.Quantity -= 20000; UnlockPlot(fiefdom); UnlockPlot(fiefdom); } break; } db.SaveChanges(); } }
/// <summary> /// Set up the data and game state for the test run /// </summary> public static void InitialiseGameState() { //game = new Game(); //server = new Server(); //client = new TestClient(); Username = "******"; Pass = "******"; MyPlayerCharacter = Globals_Game.ownedPlayerCharacters[Username]; #if DEBUG // We want to run the test with constants, so we set the success chance to 100 to remove random element MyPlayerCharacter.fixedSuccessChance = 100; #endif Dictionary <string, PlayerCharacter> .Enumerator e = Globals_Game.pcMasterList.GetEnumerator(); e.MoveNext(); NotMyPlayerCharacter = e.Current.Value; while (NotMyPlayerCharacter == MyPlayerCharacter) { e.MoveNext(); NotMyPlayerCharacter = e.Current.Value; } if (MyPlayerCharacter.myArmies != null && MyPlayerCharacter.myArmies.Count > 0) { OwnedArmy = MyPlayerCharacter.myArmies[0]; } else { Army army = new Army(Globals_Game.GetNextArmyID(), null, MyPlayerCharacter.charID, 30, NotMyPlayerCharacter.location.id, false, trp: new uint[] { 5, 5, 5, 5, 5, 5 }); OwnedArmy = army; OwnedArmy.AddArmy(); } if (NotMyPlayerCharacter.myArmies != null && NotMyPlayerCharacter.myArmies.Count > 0) { NotOwnedArmy = NotMyPlayerCharacter.myArmies[0]; } else { Army army = new Army(Globals_Game.GetNextArmyID(), null, NotMyPlayerCharacter.charID, 30, NotMyPlayerCharacter.location.id, false, trp: new uint[] { 5, 5, 5, 5, 5, 5 }); NotOwnedArmy = army; NotOwnedArmy.AddArmy(); } if (MyPlayerCharacter.ownedFiefs != null && MyPlayerCharacter.ownedFiefs.Count > 0) { OwnedFief = MyPlayerCharacter.ownedFiefs[0]; } if (NotMyPlayerCharacter.ownedFiefs != null && NotMyPlayerCharacter.ownedFiefs.Count > 0) { NotOwnedFief = NotMyPlayerCharacter.ownedFiefs[0]; } }
public async Task RequestFiefdomData() { //int test = new FiefContext().FiefdomResources.Where(f => f.Id == 2).FirstOrDefault().Quantity; Fief fief = FiefdomActions.GetFiefdomBySessionId(Context.ConnectionId); if (fief != null) { await Clients.Caller.SendAsync("RecieveFiefdomData", fief.FiefdomPlot, fief.FiefdomResources, fief.Title); } else { await Clients.Caller.SendAsync("RecieveFiefdomData", null); } }
/// <summary> /// Adds route /// </summary> /// <returns>bool indicating success</returns> /// <param name="s">Source hex (Fief)</param> /// <param name="t">Target hex (Fief)</param> /// <param name="tag">String tag for route</param> /// <param name="cost">Cost for route</param> public bool AddRoute(Fief s, Fief t, string tag, double cost) { bool success = false; // create route TaggedEdge <Fief, string> myEdge = this.CreateEdge(s, t, tag); // add route success = this.myMap.AddEdge(myEdge); // if successful, add route cost if (success) { this.AddCost(myEdge, cost); } return(success); }
public static void UnlockPlot(Fief fief) { int theta = 0; for (int x = 4; x >= 0 && x <= 9; x += theta) { if (fief.FiefdomPlot[x].Type == "Locked") { fief.FiefdomPlot[x].Type = "Empty"; return; } theta += theta > 0 ? 1 : -1; theta = -theta; } }
/// <summary> /// Test stub for spy character /// </summary> /// <param name="testClient"></param> /// <param name="charID"></param> /// <param name="targetID"></param> /// <param name="DoSpy"></param> public void SpyFiefTest(TestClient testClient, string charID, string targetID, bool DoSpy) { Character spy = Globals_Game.getCharFromID(charID); Client client = Globals_Server.Clients[testClient.playerID]; bool ownSpy = true; if (spy != null) { ownSpy = (spy.GetPlayerCharacter().Equals(client.myPlayerCharacter)); } testClient.SpyOnFief(charID, targetID); Task <ProtoMessage> responseTask = testClient.GetReply(); responseTask.Wait(); ProtoMessage response = responseTask.Result; if (string.IsNullOrWhiteSpace(charID) || string.IsNullOrWhiteSpace(targetID)) { Assert.AreEqual(DisplayMessages.ErrorGenericMessageInvalid, response.ResponseType); return; } Fief target = null; Globals_Game.fiefMasterList.TryGetValue(targetID, out target); if (spy == null || target == null) { Assert.AreEqual(DisplayMessages.ErrorGenericCharacterUnidentified, response.ResponseType); return; } if (!ownSpy) { Assert.AreEqual(DisplayMessages.ErrorGenericUnauthorised, response.ResponseType); return; } if (spy.location != target) { Assert.AreEqual(DisplayMessages.ErrorGenericNotInSameFief, response.ResponseType); return; } if (spy.days < 10) { Assert.AreEqual(DisplayMessages.ErrorGenericNotEnoughDays, response.ResponseType); return; } }
/// <summary> /// 'Helper' method to identify the shortest path between 2 hexes (Fiefs), /// then to convert path into a string for visual display /// </summary> /// <returns>String to display</returns> /// <param name="from">Source Fief</param> /// <param name="to">Target Fief</param> public string GetShortestPathString(Fief @from, Fief to) { string output = ""; var edgeCost = AlgorithmExtensions.GetIndexer(costs); var tryGetPath = myMap.ShortestPathsDijkstra(edgeCost, @from); IEnumerable <TaggedEdge <Fief, string> > path; if (tryGetPath(to, out path)) { output = PrintPath(@from, to, path); } else { output = "No path found from " + @from.id + " to " + to.id; } return(output); }
/// <summary> /// Adds hex (vertex) and route (edge) in one operation. /// Existing hexes and routes will be ignored /// </summary> /// <returns>bool indicating success</returns> /// <param name="s">Source hex (Fief)</param> /// <param name="t">Target hex (Fief)</param> /// <param name="tag">String tag for route</param> /// <param name="cost">Cost for route</param> public bool AddHexesAndRoute(Fief s, Fief t, string tag, double cost) { bool success = false; // create route TaggedEdge <Fief, string> myEdge = this.CreateEdge(s, t, tag); // use route as source to add route and hex to graph success = this.myMap.AddVerticesAndEdge(myEdge); // if successful, add route cost if (success) { this.AddCost(myEdge, cost); } return(success); }
/// <summary> /// Writes a Fief or Fief_Serialised object to the database /// </summary> /// <returns>bool indicating success</returns> /// <param name="gameID">Game (bucket) to write to</param> /// <param name="f">Fief to write</param> /// <param name="fs">Fief_Serialised to write</param> public static bool DatabaseWrite_Fief(string gameID, Fief f = null, Fief_Serialised fs = null) { if (f != null) { // convert Fief to Fief_Serialised fs = DatabaseWrite.Fief_serialise(f); } var rFief = new RiakObject(gameID, fs.id, fs); var putFiefResult = Globals_Server.rClient.Put(rFief); if (!putFiefResult.IsSuccess) { Globals_Server.logError("Write failed: Fief " + rFief.Key + " to bucket " + rFief.Bucket); } return(putFiefResult.IsSuccess); }
public static void UpdateResources(Fief fief) { foreach (FiefdomPlot plot in fief.FiefdomPlot) { switch (plot.Type) { case "Inn": fief.FiefdomResources.Where(r => r.Type == "Gold").FirstOrDefault().Quantity += 50; break; case "Gold": fief.FiefdomResources.Where(r => r.Type == "Wood").FirstOrDefault().Quantity += 3; fief.FiefdomResources.Where(r => r.Type == "Food").FirstOrDefault().Quantity += 3; fief.FiefdomResources.Where(r => r.Type == "Stone").FirstOrDefault().Quantity += 3; break; case "Barracks": var stone = fief.FiefdomResources.Where(r => r.Type == "Stone").FirstOrDefault(); var wood = fief.FiefdomResources.Where(r => r.Type == "Wood").FirstOrDefault(); if (stone.Quantity >= 5 && wood.Quantity >= 5) { fief.FiefdomResources.Where(r => r.Type == "Gold").FirstOrDefault().Quantity += 1000; stone.Quantity -= 5; wood.Quantity -= 5; } break; case "WoodCutter": fief.FiefdomResources.Where(r => r.Type == "Wood").FirstOrDefault().Quantity += 10; break; case "Farm": fief.FiefdomResources.Where(r => r.Type == "Food").FirstOrDefault().Quantity += 10; break; case "Quarry": fief.FiefdomResources.Where(r => r.Type == "Stone").FirstOrDefault().Quantity += 10; break; default: break; } } }
public static void BuildPlot(string sessionId, int id, string type) { using (var db = new FiefContext()) { List <FiefdomResources> cost = new List <FiefdomResources> { new FiefdomResources { Type = "Gold", Quantity = 500 }, new FiefdomResources { Type = "Food", Quantity = 5 }, new FiefdomResources { Type = "Stone", Quantity = 5 }, new FiefdomResources { Type = "Wood", Quantity = 5 } }; Fief fief = db.Fiefdom.Where(f => f.SessionId == sessionId).Include("FiefdomPlot").Include("FiefdomResources").FirstOrDefault(); bool canAfford = true; foreach (var res in cost) { if (fief.FiefdomResources.Where(t => t.Type == res.Type).FirstOrDefault().Quantity < res.Quantity) { canAfford = false; } } //Subtract resources if (canAfford == true) { if (fief.FiefdomPlot[id].Type == "Empty") { fief.FiefdomPlot[id].Type = type; foreach (var res in cost) { fief.FiefdomResources.Where(t => t.Type == res.Type).FirstOrDefault().Quantity -= res.Quantity; } } } db.SaveChanges(); } }
/// <summary> /// Method to determine if player has permission to view fief /// </summary> /// <param name="pc">PlayerCharacter who wants to view fief</param> /// <param name="o">Fief to view</param> /// <returns>Whether or not a character can see a fief</returns> public static bool canSeeFief(PlayerCharacter pc, object o) { Fief f = o as Fief; if (pc.ownedFiefs.Contains(f)) { return true; } bool isInFief = (pc.location == f); // Note: Captives cannot see anything if (isInFief&&string.IsNullOrWhiteSpace(pc.captorID)) return true; foreach (Character character in pc.myNPCs) { if (character.location == f && string.IsNullOrWhiteSpace(character.captorID)) { return true; } } return false; }
public static void CreateNewFiefdom(string name, string sessionId) { using (var db = new FiefContext()) { Fief fief = new Fief { Name = name, SessionId = sessionId, Title = 0 }; fief.FiefdomResources.Add(new FiefdomResources { Type = "Gold", Quantity = 200 }); fief.FiefdomResources.Add(new FiefdomResources { Type = "Wood", Quantity = 10 }); fief.FiefdomResources.Add(new FiefdomResources { Type = "Stone", Quantity = 10 }); fief.FiefdomResources.Add(new FiefdomResources { Type = "Food", Quantity = 10 }); if (db.Market.ToList().Count == 0) { db.Market.Add(new Market { Type = "Wood", Price = 10 }); db.Market.Add(new Market { Type = "Food", Price = 10 }); db.Market.Add(new Market { Type = "Stone", Price = 10 }); } for (int i = 0; i < 10; i++) { fief.FiefdomPlot.Add(new FiefdomPlot { Type = "Locked" }); } fief.FiefdomPlot[4].Type = "Empty"; db.Fiefdom.Add(fief); db.SaveChanges(); } }
/// <summary> /// Identify the shortest path between 2 hexes (Fiefs) /// </summary> /// <returns>Queue of Fiefs to move to</returns> /// <param name="from">Source Fief</param> /// <param name="to">Target Fief</param> public Queue <Fief> GetShortestPath(Fief @from, Fief to) { Queue <Fief> pathNodes = new Queue <Fief>(); var edgeCost = AlgorithmExtensions.GetIndexer(costs); // get shortest route using Dijkstra algorithm var tryGetPath = myMap.ShortestPathsDijkstra(edgeCost, @from); IEnumerable <TaggedEdge <Fief, string> > path; // iterate through resulting routes (edges) if (tryGetPath(to, out path)) { // extract target Fiefs and add to queue foreach (var e in path) { pathNodes.Enqueue(e.Target); } } return(pathNodes); }
/// <summary> /// Identify a route and retrieve the target fief /// </summary> /// <returns>Fief to move to (or null)</returns> /// <param name="f">Current location of NPC</param> /// <param name="f">Direction to move (route tag)</param> public Fief GetFief(Fief f, string direction) { Fief myFief = null; // check for correct direction codes string[] correctDirections = new string[8] { "E", "W", "SE", "SW", "NE", "NW", "N", "S" }; bool dirCorrect = false; foreach (string correctDir in correctDirections) { if (direction.ToUpper().Equals(correctDir)) { dirCorrect = true; break; } } // iterate through edges if (dirCorrect) { foreach (var e in this.myMap.Edges) { // if matching source, check tag if (e.Source == f) { // if matching tag, get target if (e.Tag.Equals(direction)) { myFief = e.Target; break; } } } } return(myFief); }
public static void UpdateResources(Fief fief) { foreach (FiefdomPlot plot in fief.FiefdomPlot) { switch (plot.Type) { case "Woodcutter": fief.FiefdomResources.Where(r => r.Type == "Wood").FirstOrDefault().Quantity += 1; break; case "Farm": fief.FiefdomResources.Where(r => r.Type == "Food").FirstOrDefault().Quantity += 1; break; case "Quarry": fief.FiefdomResources.Where(r => r.Type == "Stone").FirstOrDefault().Quantity += 1; break; default: break; } } }
public async Task <FiefLookupDto> Handle(CreateFiefCommand request, CancellationToken cancellationToken) { if (Guid.TryParse(request.GameSessionId, out Guid id)) { var session = await _context.GameSessions.FindAsync(id); if (session != null) { if (session.User == _user) { var count = session.Fiefs.Count; var fief = new Fief { Name = $"Förläning {count++}" }; session.Fiefs.Add(fief); await _context.SaveChangesAsync(cancellationToken); fief.Livingcondition.LivingconditionType = await _context.LivingconditionTypes.Where(o => o.LivingconditionTypeId == 3).FirstAsync(); fief.Road.RoadType = await _context.RoadTypes.Where(o => o.RoadTypeId == 2).FirstAsync(); fief.Inheritance.InheritanceType = await _context.InheritanceTypes.Where(o => o.InheritanceTypeId == 1).FirstAsync(); return(_mapper.Map <FiefLookupDto>(fief)); } // GameSession does not belong to the user. return(null); } // GameSession with id could not be found. return(null); } // GameSessionId could not be parsed to a Guid. return(null); }
/// <summary> /// Selects random adjoining hex (also equal chance to select current hex) /// </summary> /// <returns>Fief to move to (or null)</returns> /// <param name="from">Current fief</param> /// <param name="getOwned">bool indicating whether or not to try to return an owned fief</param> /// <param name="owner">owner, when looking for an owned fief</param> /// <param name="avoid">Fief to avoid (for retreats)</param> public Fief chooseRandomHex(Fief from, bool getOwned = false, PlayerCharacter fiefOwner = null, Fief avoid = null) { // list to store all edges List <TaggedEdge <Fief, string> > choices = new List <TaggedEdge <Fief, string> >(); // list to store all edges to owned fiefs List <TaggedEdge <Fief, string> > ownedChoices = new List <TaggedEdge <Fief, string> >(); // int to use in edge selection int selection = 0; // string to contain chosen move direction Fief goTo = null; // identify and store all target hexes from source hex foreach (var e in this.myMap.Edges) { bool okToAdd = true; if (e.Source == from) { // no 'avoid' fief specified if (avoid == null) { okToAdd = true; } // if 'avoid' fief specified else { // if is NOT specified 'avoid' fief if (e.Target != avoid) { okToAdd = true; } // if IS specified 'avoid' fief else { okToAdd = false; } } if (okToAdd) { choices.Add(e); // if getOwned, also check for target ownership if (getOwned) { if (e.Target.owner == fiefOwner) { ownedChoices.Add(e); } } } } } // if looking for owned fief, get one if possible if ((getOwned) && (ownedChoices.Count > 0)) { // choose fief by generating random int between 0 and no. of targets selection = Globals_Game.myRand.Next(0, ownedChoices.Count); // get Fief goTo = ownedChoices[selection].Target; } // if ownership not required, choose from all adjoining fiefs else if (choices.Count > 0) { // choose fief by generating random int between 0 and no. of targets selection = Globals_Game.myRand.Next(0, choices.Count); // get Fief goTo = choices[selection].Target; } return(goTo); }
/// <summary>Test stub for AdjustExpenditure(String, Double, Double, Double, Double, Double)</summary> public void AdjustExpenditureTest( TestClient TestClient, string fiefID, double newTax, double newOff, double newGarr, double newKeep, double newInfra ) { TestClient.AdjustExpenditure(fiefID, newTax, newOff, newGarr, newKeep, newInfra); Client client = null; if (!ValidClientState(TestClient, out client)) { Task <string> ReplyTask = TestClient.GetServerMessage(); ReplyTask.Wait(); string reply = ReplyTask.Result; Assert.AreEqual("Not logged in- Disconnecting", reply); return; } // If not a valid fief, expect to fail if (string.IsNullOrWhiteSpace(fiefID) || !Globals_Game.fiefKeys.Contains(fiefID)) { Console.Write("not a fief Id "); Task <ProtoMessage> ReplyTask = TestClient.GetReply(); ReplyTask.Wait(); ProtoMessage reply = ReplyTask.Result; Assert.AreEqual(reply.ResponseType, DisplayMessages.ErrorGenericFiefUnidentified); } else { Task <ProtoMessage> ReplyTask = TestClient.GetReply(); ReplyTask.Wait(); ProtoMessage reply = ReplyTask.Result; // If not fief owner expect unauthorised Fief fief = null; Globals_Game.fiefMasterList.TryGetValue(fiefID, out fief); if (fief.owner != client.myPlayerCharacter) { Assert.AreEqual(reply.ResponseType, DisplayMessages.ErrorGenericUnauthorised); } // If numbers invalid expect an invalid exception else if (newTax < 0 || newOff < 0 || newGarr < 0 || newKeep < 0 || newInfra < 0) { Assert.AreEqual(reply.ResponseType, DisplayMessages.ErrorGenericMessageInvalid); } else { if (reply.GetType() == typeof(ProtoFief)) { Assert.AreEqual(DisplayMessages.FiefExpenditureAdjusted, reply.ResponseType); } else { Assert.AreEqual(DisplayMessages.FiefExpenditureAdjustment, reply.ResponseType); } } } }
public static bool OverlordOfFief(PlayerCharacter pc, object o) { if (o == null) return false; Fief fief = (Fief)o; return (fief.GetOverlord() == pc); }
public static bool OwnsFief(PlayerCharacter pc, object o) { if (o == null) return false; Fief fief = (Fief)o; return (fief.owner == pc); }
public static void InitialiseGameState(TestContext ctx = null) { Globals_Server.LogFile = new System.IO.StreamWriter("LogFile.txt"); Globals_Server.LogFile.AutoFlush = true; game = new Game(); server = new Server(); client = new TestClient(); Username = "******"; Pass = "******"; OtherUser = "******"; OtherPass = "******"; BadUsername = "******"; BadPass = "******"; MyPlayerCharacter = Globals_Game.ownedPlayerCharacters[Username]; Dictionary <string, PlayerCharacter> .Enumerator e = Globals_Game.pcMasterList.GetEnumerator(); e.MoveNext(); NotMyPlayerCharacter = e.Current.Value; while (NotMyPlayerCharacter == MyPlayerCharacter) { e.MoveNext(); NotMyPlayerCharacter = e.Current.Value; } foreach (NonPlayerCharacter npc in MyPlayerCharacter.myNPCs) { if (!string.IsNullOrWhiteSpace(npc.familyID)) { MyFamily = npc; } else if (!string.IsNullOrWhiteSpace(npc.employer)) { MyEmployee = npc; } if (MyEmployee != null && MyFamily != null) { break; } } foreach (NonPlayerCharacter npc in NotMyPlayerCharacter.myNPCs) { if (!string.IsNullOrWhiteSpace(npc.familyID)) { NotMyFamily = npc; } else if (!string.IsNullOrWhiteSpace(npc.employer)) { NotMyEmplployee = npc; } if (NotMyEmplployee != null && NotMyFamily != null) { break; } } if (MyPlayerCharacter.myArmies != null && MyPlayerCharacter.myArmies.Count > 0) { OwnedArmy = MyPlayerCharacter.myArmies[0]; } else { Army army = new Army(Globals_Game.GetNextArmyID(), null, MyPlayerCharacter.charID, 30, NotMyPlayerCharacter.location.id, false, trp: new uint[] { 5, 5, 5, 5, 5, 5, 5 }); OwnedArmy = army; OwnedArmy.AddArmy(); } if (NotMyPlayerCharacter.myArmies != null && NotMyPlayerCharacter.myArmies.Count > 0) { NotOwnedArmy = NotMyPlayerCharacter.myArmies[0]; } else { Army army = new Army(Globals_Game.GetNextArmyID(), null, NotMyPlayerCharacter.charID, 30, NotMyPlayerCharacter.location.id, false, trp: new uint[] { 5, 5, 5, 5, 5, 5, 5 }); NotOwnedArmy = army; NotOwnedArmy.AddArmy(); } if (MyPlayerCharacter.ownedFiefs != null && MyPlayerCharacter.ownedFiefs.Count > 0) { OwnedFief = MyPlayerCharacter.ownedFiefs[0]; } if (NotMyPlayerCharacter.ownedFiefs != null && NotMyPlayerCharacter.ownedFiefs.Count > 0) { NotOwnedFief = NotMyPlayerCharacter.ownedFiefs[0]; } foreach (var npc in Globals_Game.npcMasterList) { if (npc.Value.GetPlayerCharacter() == null) { NobodysCharacter = npc.Value; } } client.LogInAndConnect(Username, Pass, new byte[] { 1, 2, 3, 4, 5, 6 }); while (!client.IsConnectedAndLoggedIn()) { Thread.Sleep(0); } client.ClearMessageQueues(); }
/// <summary> /// Returns the Fief id (used in serialization) /// </summary> /// <param name="f">Fief to get id from</param> /// <returns></returns> public string getIdFromFief(Fief f) { return(f.id); }
/// <summary> /// Calculates the outcome of the pillage of a fief by an army /// </summary> /// <param name="f">The fief being pillaged</param> /// <param name="a">The pillaging army</param> /// <param name="circumstance">The circumstance under which the fief is being pillaged</param> public static ProtoPillageResult ProcessPillage(Fief f, Army a, string circumstance = "pillage") { ProtoPillageResult pillageResult = new ProtoPillageResult(); double thisLoss = 0; double moneyPillagedTotal = 0; double moneyPillagedOwner = 0; double pillageMultiplier = 0; // get army leader Character armyLeader = a.GetLeader(); // get pillaging army owner (receives a proportion of total spoils) PlayerCharacter armyOwner = a.GetOwner(); pillageResult.fiefID = f.id; // get garrison leader (to add to journal entry) Character defenderLeader = null; if (f.bailiff != null) { defenderLeader = f.bailiff; } // calculate pillageMultiplier (based on no. pillagers per 1000 population) pillageMultiplier = a.CalcArmySize() / (f.population / 1000); // calculate days taken for pillage double daysTaken = Globals_Game.myRand.Next(7, 16); if (daysTaken > a.days) { daysTaken = a.days; } // update army days armyLeader.AdjustDays(daysTaken); pillageResult.daysTaken = daysTaken; // % population loss thisLoss = (0.007 * pillageMultiplier); // ensure is between 1%-20% if (thisLoss < 1) { thisLoss = 1; } else if (thisLoss > 20) { thisLoss = 20; } // apply population loss pillageResult.populationLoss = Convert.ToInt32((f.population * (thisLoss / 100))); f.population -= Convert.ToInt32((f.population * (thisLoss / 100))); // % treasury loss if (!circumstance.Equals("quellRebellion")) { thisLoss = (0.2 * pillageMultiplier); // ensure is between 1%-80% if (thisLoss < 1) { thisLoss = 1; } else if (thisLoss > 80) { thisLoss = 80; } // apply treasury loss if (f.Treasury > 0) { pillageResult.treasuryLoss = Convert.ToInt32((f.Treasury * (thisLoss / 100))); f.AdjustTreasury(-Convert.ToInt32((f.Treasury * (thisLoss / 100)))); } } // % loyalty loss thisLoss = (0.33 * pillageMultiplier); // ensure is between 1%-20% if (thisLoss < 1) { thisLoss = 1; } else if (thisLoss > 20) { thisLoss = 20; } // apply loyalty loss pillageResult.loyaltyLoss = (f.loyalty * (thisLoss / 100)); f.loyalty -= (f.loyalty * (thisLoss / 100)); // % fields loss thisLoss = (0.01 * pillageMultiplier); // ensure is between 1%-20% if (thisLoss < 1) { thisLoss = 1; } else if (thisLoss > 20) { thisLoss = 20; } // apply fields loss pillageResult.fieldsLoss = (f.fields * (thisLoss / 100)); f.fields -= (f.fields * (thisLoss / 100)); // % industry loss thisLoss = (0.01 * pillageMultiplier); // ensure is between 1%-20% if (thisLoss < 1) { thisLoss = 1; } else if (thisLoss > 20) { thisLoss = 20; } // apply industry loss pillageResult.industryLoss = (f.industry * (thisLoss / Convert.ToDouble(100))); f.industry -= (f.industry * (thisLoss / 100)); // money pillaged (based on GDP) thisLoss = (0.032 * pillageMultiplier); // ensure is between 1%-50% if (thisLoss < 1) { thisLoss = 1; } else if (thisLoss > 50) { thisLoss = 50; } // calculate base amount pillaged based on fief GDP double baseMoneyPillaged = (f.keyStatsCurrent[1] * (thisLoss / 100)); moneyPillagedTotal = baseMoneyPillaged; pillageResult.baseMoneyPillaged = baseMoneyPillaged; // factor in no. days spent pillaging (get extra 5% per day > 7) int daysOver7 = Convert.ToInt32(daysTaken) - 7; if (daysOver7 > 0) { for (int i = 0; i < daysOver7; i++) { moneyPillagedTotal += (baseMoneyPillaged * 0.05); } pillageResult.bonusMoneyPillaged = moneyPillagedTotal - baseMoneyPillaged; pillageResult.daysTaken = daysOver7; } // check for jackpot // generate randomPercentage to see if hit the jackpot int myRandomPercent = Globals_Game.myRand.Next(101); if (myRandomPercent <= 30) { // generate random int to multiply amount pillaged int myRandomMultiplier = Globals_Game.myRand.Next(3, 11); pillageResult.jackpot = moneyPillagedTotal * myRandomMultiplier - moneyPillagedTotal; moneyPillagedTotal = moneyPillagedTotal * myRandomMultiplier; } // check proportion of money pillaged goes to army owner (based on stature) double proportionForOwner = 0.05 * armyOwner.CalculateStature(); moneyPillagedOwner = (moneyPillagedTotal * proportionForOwner); pillageResult.moneyPillagedOwner = moneyPillagedOwner; // apply to army owner's home fief treasury armyOwner.GetHomeFief().AdjustTreasury(Convert.ToInt32(moneyPillagedOwner)); // apply loss of stature to army owner if fief has same language if (armyOwner.language.id == f.language.id) { armyOwner.AdjustStatureModifier(-0.3); pillageResult.statureModifier = (-0.3); } else if (armyOwner.language.baseLanguage.id == f.language.baseLanguage.id) { armyOwner.AdjustStatureModifier(-0.2); pillageResult.statureModifier = (-0.2); } // set isPillaged for fief f.isPillaged = true; // =================== construct and send JOURNAL ENTRY // ID uint entryID = Globals_Game.GetNextJournalEntryID(); // personae List <string> tempPersonae = new List <string>(); tempPersonae.Add(f.owner.charID + "|fiefOwner"); tempPersonae.Add(armyOwner.charID + "|attackerOwner"); if (armyLeader != null) { tempPersonae.Add(armyLeader.charID + "|attackerLeader"); } if ((defenderLeader != null) && (!circumstance.Equals("quellRebellion"))) { tempPersonae.Add(defenderLeader.charID + "|defenderLeader"); } if (circumstance.Equals("quellRebellion")) { tempPersonae.Add("all|all"); } string[] pillagePersonae = tempPersonae.ToArray(); // location string pillageLocation = f.id; // type string type = ""; if (circumstance.Equals("pillage")) { type += "pillage"; } else if (circumstance.Equals("quellRebellion")) { type += "rebellionQuelled"; } if (circumstance.Equals("pillage")) { pillageResult.isPillage = true; } else if (circumstance.Equals("quellRebellion")) { pillageResult.isPillage = false; } pillageResult.fiefName = f.name; pillageResult.fiefOwner = f.owner.firstName + " " + f.owner.familyName; if ((circumstance.Equals("pillage")) && (defenderLeader != null)) { if (f.owner != defenderLeader) { pillageResult.defenderLeader = defenderLeader.firstName + " " + defenderLeader.familyName; } } pillageResult.armyOwner = armyOwner.firstName + " " + armyOwner.familyName; if (armyLeader != null) { pillageResult.armyLeader = armyLeader.firstName + " " + armyLeader.familyName; } // put together new journal entry JournalEntry pillageEntry = new JournalEntry(pillageResult, entryID, Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason, pillagePersonae, type, loc: pillageLocation); // add new journal entry to pastEvents Globals_Game.AddPastEvent(pillageEntry); return(pillageResult); }
/// <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); }
/// <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> /// 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); }