示例#1
0
        /// <summary>
        /// forges alliance between character a and character b families. depending on how the alliance was forged an identifier would be used to determine so
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="x"></param>
        /// <returns></returns>
        public static void forgeAlliance(String a, String b)
        {
            Character aC = Globals_Game.getCharFromID(a);
            Character bC = Globals_Game.getCharFromID(b);

            if (!aC.isAlly(bC) && !bC.isAlly(aC))
            {
                for (int i = 0; i < Globals_Game.npcMasterList.Count; i++)
                {
                    if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                    {
                        Globals_Game.npcMasterList.Values.ElementAt(i).allies.Add(aC.familyID);
                    }
                    if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                    {
                        Globals_Game.npcMasterList.Values.ElementAt(i).allies.Add(bC.familyID);
                    }
                }
                for (int i = 0; i < Globals_Game.pcMasterList.Count; i++)
                {
                    if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                    {
                        Globals_Game.pcMasterList.Values.ElementAt(i).allies.Add(aC.familyID);
                    }
                    if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                    {
                        Globals_Game.pcMasterList.Values.ElementAt(i).allies.Add(bC.familyID);
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Breaks alliance between Character a family and Character b family
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void removeAlly(String a, String b)
        {
            Character aC = Globals_Game.getCharFromID(a);
            Character bC = Globals_Game.getCharFromID(b);


            for (int i = 0; i < Globals_Game.npcMasterList.Count; i++)
            {
                if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                {
                    Globals_Game.npcMasterList.Values.ElementAt(i).allies.Remove(aC.familyID);
                }
                if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                {
                    Globals_Game.npcMasterList.Values.ElementAt(i).allies.Remove(bC.familyID);
                }
            }
            for (int i = 0; i < Globals_Game.pcMasterList.Count; i++)
            {
                if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                {
                    Globals_Game.pcMasterList.Values.ElementAt(i).allies.Remove(aC.familyID);
                }
                if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                {
                    Globals_Game.pcMasterList.Values.ElementAt(i).allies.Remove(bC.familyID);
                }
            }
        }
示例#3
0
        /// <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>
        /// Assert that the test client is logged in, has a PlayerCharacter and is a registered observer
        /// </summary>
        /// <param name="testClient"></param>
        /// <param name="client"></param>
        /// <returns></returns>
        public bool ValidClientState(TestClient testClient, out Client client)
        {
            if (testClient.net == null || !testClient.IsConnectedAndLoggedIn())
            {
                client = null;
                return(false);
            }
            // If do not have a PlayerCharacter, are dead etc, expect to fail
            Globals_Server.Clients.TryGetValue(testClient.playerID, out client);
            if (client == null)
            {
                Assert.AreEqual(testClient.net.GetConnectionStatusString(), "Disconnected");
                return(false);
            }

            if (client.myPlayerCharacter == null || !client.myPlayerCharacter.isAlive)
            {
                Task <string> ReplyTask = testClient.GetServerMessage();
                ReplyTask.Wait();
                string reply = ReplyTask.Result;
                Assert.AreEqual(reply, "You have no valid PlayerCharacter!");
                return(false);
            }
            if (!Globals_Game.IsObserver(client))
            {
                return(false);
            }
            return(true);
        }
示例#5
0
        /// <summary>
        /// Adds all characters from family A and B to each others "At War" lists
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void declareWar(string a, string b)
        {
            Character aC = Globals_Game.getCharFromID(a);
            Character bC = Globals_Game.getCharFromID(b);


            for (int i = 0; i < Globals_Game.npcMasterList.Count; i++)
            {
                if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                {
                    Globals_Game.npcMasterList.Values.ElementAt(i).atWar.Add(aC.familyID);
                }
                if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                {
                    Globals_Game.npcMasterList.Values.ElementAt(i).atWar.Add(bC.familyID);
                }
            }
            for (int i = 0; i < Globals_Game.pcMasterList.Count; i++)
            {
                if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                {
                    Globals_Game.pcMasterList.Values.ElementAt(i).atWar.Add(aC.familyID);
                }
                if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                {
                    Globals_Game.pcMasterList.Values.ElementAt(i).atWar.Add(bC.familyID);
                }
            }
        }
示例#6
0
        /// <summary>
        /// Removes character A and B families from each other "At War" lists
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        public static void makePeace(string a, string b)
        {
            Character aC = Globals_Game.getCharFromID(a);
            Character bC = Globals_Game.getCharFromID(b);

            if (aC.wagingWar(bC) && bC.wagingWar(aC))
            {
                for (int i = 0; i < Globals_Game.npcMasterList.Count; i++)
                {
                    if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                    {
                        Globals_Game.npcMasterList.Values.ElementAt(i).atWar.Remove(aC.familyID);
                    }
                    if (Globals_Game.npcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                    {
                        Globals_Game.npcMasterList.Values.ElementAt(i).atWar.Remove(bC.familyID);
                    }
                }
                for (int i = 0; i < Globals_Game.pcMasterList.Count; i++)
                {
                    if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(bC.familyID))
                    {
                        Globals_Game.pcMasterList.Values.ElementAt(i).atWar.Remove(aC.familyID);
                    }
                    if (Globals_Game.pcMasterList.Values.ElementAt(i).familyID.Equals(aC.familyID))
                    {
                        Globals_Game.pcMasterList.Values.ElementAt(i).atWar.Remove(bC.familyID);
                    }
                }
            }
        }
示例#7
0
        public Client deserialise()
        {
            Client c = new Client(user, pcID);

            c.myPastEvents      = this.myPastEvents;
            c.myPlayerCharacter = Globals_Game.getCharFromID(pcID) as PlayerCharacter;
            c.activeChar        = Globals_Game.getCharFromID(activeChar);
            return(c);
        }
        /// <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 SpyCharacterTest(TestClient testClient, string charID, string targetID, bool DoSpy)
        {
            bool      ownsCharacter = true;
            Character spy           = Globals_Game.getCharFromID(charID);
            Client    client        = Globals_Server.Clients[testClient.playerID];

            if (spy != null)
            {
                ownsCharacter = (spy.GetPlayerCharacter().Equals(client.myPlayerCharacter));
            }
            testClient.SpyOnCharacter(charID, targetID);
            Task <ProtoMessage> responseTask = testClient.GetReply();

            responseTask.Wait();
            ProtoMessage response = responseTask.Result;

            // If don't identify either character, CharacterUnidentified error
            // If don't own spy, PermissionDenied error
            // If target is own character, SpyCharacterOwn error
            // If target is not in same fief as spy, TooFarFromFief error
            // If target is not valid, other error
            // Otherwise, expect a response

            if (string.IsNullOrWhiteSpace(charID) || string.IsNullOrWhiteSpace(targetID))
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericMessageInvalid, response.ResponseType);
                return;
            }
            Character target = Globals_Game.getCharFromID(targetID);

            if (spy == null || target == null)
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericCharacterUnidentified, response.ResponseType);
                return;
            }

            if (!ownsCharacter)
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericUnauthorised, response.ResponseType);
                return;
            }
            if (spy.location != target.location)
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericNotInSameFief, response.ResponseType);
                return;
            }
            if (spy.days < 10)
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericNotEnoughDays, response.ResponseType);
                return;
            }
            if (target.GetPlayerCharacter() == spy.GetPlayerCharacter())
            {
                Assert.AreEqual(DisplayMessages.ErrorSpyOwn, response.ResponseType);
                return;
            }
        }
示例#9
0
 public void LogInTwiceAsDifferentUsers()
 {
     // Tell the client it isn't logged in
     client.net.loggedIn = false;
     // Try to log in as anothr user
     client.LogInAndConnect(OtherUser, OtherPass, new byte[] { 1, 2, 3, 4, 5, 6, 7 });
     while (!client.IsConnectedAndLoggedIn())
     {
         Thread.Sleep(0);
     }
     Assert.IsFalse(Globals_Game.IsObserver(OtherUser));
 }
示例#10
0
        /// <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];
            }
        }
示例#11
0
        ///// <summary>
        ///// The main entry point for the application.
        ///// </summary>
        //static void Main()
        //{

        //    try
        //    {
        //        using (Globals_Server.LogFile = new System.IO.StreamWriter("LogFile.txt"))
        //        {

        //            //Globals_Server.rCluster = RiakCluster.FromConfig("riakConfig","app.config");
        //            //Globals_Server.rClient = Globals_Server.rCluster.CreateClient();
        //            Globals_Server.LogFile.AutoFlush = true;
        //            Globals_Server.logEvent("Server start");

        //            Game game = new Game();
        //            SetUpForDemo();
        //            /*
        //            //DatabaseWrite.DatabaseWriteAll ("testBucket");

        //            /*if (Globals_Server.rClient.Ping ().IsSuccess) {
        //                Console.WriteLine ("Database connection successful");
        //                string gameID = "testBucket";
        //                foreach (string trait in Globals_Game.traitKeys) {
        //                    Console.WriteLine (trait);
        //                }

        //                // Test can read from database
        //                var newClient = Globals_Server.rCluster.CreateClient();
        //                RiakObject newObj = new RiakObject (gameID, "superawesome3", Globals_Game.traitKeys.ToArray ());
        //                newClient.Put (newObj);
        //                Thread.Sleep (5000);
        //                var testRead =newClient.Get (gameID, "superawesome3");
        //                if (!testRead.IsSuccess) {
        //                    Console.WriteLine ("FAIL :(" + testRead.ErrorMessage);
        //                } else {
        //                    Console.WriteLine ("Got traitkeys:");
        //                }
        //                //DatabaseRead.DatabaseReadAll (gameID);
        //            } else {
        //                Console.WriteLine ("Could not connect to database :( ");
        //            } */

        //            //testCaptives();



        //            Server server = new Server();
        //            try
        //            {
        //                //TestSuite testSuite = new TestSuite();
        //                TestClient client = new TestClient();
        //                client.LogInAndConnect("helen", "potato");
        //            }
        //            catch (Exception e)
        //            {
        //                Console.WriteLine(e.Message);
        //            }
        //            //client.LogIn("helen", "potato");
        //            String s = Console.ReadLine();
        //            if (s != null && s.Equals("exit"))
        //            {
        //                Globals_Server.logEvent("Server exits");
        //                server.isListening = false;
        //                Globals_Server.server.Shutdown("Server exits");
        //            }

        //            //testArmy();
        //            //testSpying();
        //            /*
        //                    while (true)
        //                    {

        //                        if (s != null && s.Equals("exit"))
        //                        {
        //                            Globals_Server.logEvent("Server exits");
        //                            server.isListening = false;
        //                            Globals_Server.server.Shutdown("Server exits");
        //                            break;
        //                        }

        //                    }

        //                    * */
        //            Globals_Server.LogFile.Close();

        //        }

        //    }
        //    catch (Exception e)
        //    {
        //        Globals_Server.LogFile.Close();
        //        Console.WriteLine("Encountered an error:" + e.StackTrace);
        //        Console.ReadLine();
        //    }


        //}

        /// <summary>
        /// Code which was used in the 2015 demo- sets up a few armies, adds funds and sets a few traits to demonstrate trait effects
        /// </summary>
        public static void SetUpForDemo()
        {
            // Make Anselm Marshal very sneaky
            Character Anselm = Globals_Game.getCharFromID("Char_390");
            Character Bishop = Globals_Game.getCharFromID("Char_391");

            Tuple <Trait, int>[] newTraits = new Tuple <Trait, int> [2];
            newTraits[0]  = new Tuple <Trait, int>(Globals_Game.traitMasterList["trait_9"], 9);
            newTraits[1]  = new Tuple <Trait, int>(Globals_Game.traitMasterList["trait_8"], 9);
            Anselm.traits = newTraits;
            // Make Bishop Henry Marshal not sneaky
            Tuple <Trait, int>[] newTraits2 = new Tuple <Trait, int> [1];
            newTraits2[0] = new Tuple <Trait, int>(Globals_Game.traitMasterList["trait_5"], 2);
            Bishop.traits = newTraits2;
            // Add funds to home treasury
            (Globals_Game.getCharFromID("Char_158") as PlayerCharacter).GetHomeFief().AdjustTreasury(100000);

            // create enemy character in home fief
            NonPlayerCharacter enemyGeneral  = new NonPlayerCharacter("Char_164459", "John", "Smith", new Tuple <uint, byte>(1142, 3), true, Globals_Game.nationalityMasterList["Sco"], true, 9, 9, new Queue <Fief>(), Globals_Game.languageMasterList["lang_C1"], 90, 9, 9, 9, new Tuple <Trait, int> [0], true, false, "Char_126", null, "Char_126", null, 0, false, false, new List <string>(), null, null, Globals_Game.fiefMasterList["EPM02"]);
            PlayerCharacter    factionLeader = Globals_Game.pcMasterList["Char_126"];

            factionLeader.myNPCs.Add(enemyGeneral);
            enemyGeneral.inKeep = false;
            // create enemy army for above enemy character
            uint[] enemyArmyTroops = new uint[] { 3, 7, 0, 20, 30, 65, 190 };
            Army   enemyArmy       = new Army(Globals_Game.GetNextArmyID(), Globals_Game.npcMasterList["Char_164459"].charID, Globals_Game.pcMasterList["Char_196"].charID, Globals_Game.npcMasterList["Char_164459"].days, Globals_Game.npcMasterList["Char_164459"].location.id, trp: enemyArmyTroops);

            enemyArmy.AddArmy();

            // create and add army
            uint[] myArmyTroops1 = new uint[] { 8, 10, 0, 30, 60, 100, 220 };
            Army   myArmy1       = new Army(Globals_Game.GetNextArmyID(), Globals_Game.pcMasterList["Char_196"].charID, Globals_Game.pcMasterList["Char_196"].charID, Globals_Game.pcMasterList["Char_196"].days, Globals_Game.pcMasterList["Char_196"].location.id, trp: myArmyTroops1);

            myArmy1.AddArmy();
            // create and add army
            uint[] myArmyTroops2 = new uint[] { 5, 10, 0, 30, 40, 80, 220 };
            Army   myArmy2       = new Army(Globals_Game.GetNextArmyID(), Globals_Game.pcMasterList["Char_158"].charID, Globals_Game.pcMasterList["Char_158"].charID, Globals_Game.pcMasterList["Char_158"].days, Globals_Game.pcMasterList["Char_158"].location.id, trp: myArmyTroops2, aggr: 1, odds: 2);

            myArmy2.AddArmy();

            // Add single lady appropriate for marriage
            //Nationality nat = Globals_Game.nationalityMasterList["Sco"];
            NonPlayerCharacter proposalChar = new NonPlayerCharacter("Char_626", "Mairi", "Meah", new Tuple <uint, byte>(1162, 3), false, Globals_Game.nationalityMasterList["Sco"], true, 9, 9, new Queue <Fief>(), Globals_Game.languageMasterList["lang_C1"], 90, 9, 9, 9, new Tuple <Trait, int> [0], true, false, "Char_126", null, "Char_126", null, 0, false, false, new List <string>(), null, null, Globals_Game.fiefMasterList["ESW05"]);
            PlayerCharacter    pc           = Globals_Game.pcMasterList["Char_126"];

            pc.myNPCs.Add(proposalChar);
            proposalChar.inKeep = false;
        }
示例#12
0
        /// <summary>Test stub for LogIn(String, String, Byte[])</summary>

        public void LogInTest(
            TestClient client,
            string user,
            string pass,
            byte[] key
            )
        {
            client.LogInAndConnect(user, pass, key);
            // If username not recognised, expect to be disconnected
            if (string.IsNullOrEmpty(user) || !Utility_Methods.CheckStringValid("combined", user) || !LogInManager.users.ContainsKey(user))
            {
                Assert.AreEqual("Disconnected", client.net.GetConnectionStatusString());
                return;
            }
            // If password is incorrect, expect an error
            Tuple <byte[], byte[]> hashNsalt = LogInManager.users[user];

            byte[] hash;
            if (pass == null)
            {
                hash = null;
            }
            else
            {
                hash = LogInManager.ComputeHash(System.Text.Encoding.UTF8.GetBytes(pass), hashNsalt.Item2);
            }
            if (hash == null || !hashNsalt.Item1.SequenceEqual(hash) || key == null || key.Length < 5)
            {
                Assert.AreEqual("Disconnected", client.net.GetConnectionStatusString());
                Assert.IsFalse(Server.ContainsConnection(user));
            }
            else
            {
                // If the login was successful, expecting a ProtoLogin followed by a ProtoClient back
                Task <ProtoMessage> getReply = client.GetReply();
                getReply.Wait();
                ProtoMessage reply = getReply.Result;
                Assert.AreEqual(reply.GetType(), typeof(ProtoLogIn));
                while (!client.IsConnectedAndLoggedIn())
                {
                    Thread.Sleep(0);
                }
                // If login was successful, the client should be in the list of registered observers
                Assert.IsTrue(Globals_Game.IsObserver(Globals_Server.Clients[user]));
                Assert.IsTrue(Server.ContainsConnection(user));
            }
        }
示例#13
0
        /// <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;
            }
        }
示例#14
0
        /// <summary>
        /// Processes a client disconnecting from the server- removes the client as an observer, removes their connection and deletes their CryptoServiceProvider
        /// </summary>
        /// <param name="conn">Connection of the client who disconnected</param>
        private void Disconnect(NetConnection conn)
        {
            Contract.Requires(conn != null);
            lock (ServerLock)
            {
                if (clientConnections.ContainsKey(conn))
                {
                    Client client = clientConnections[conn];
                    Globals_Server.logEvent("Client " + client.username + " disconnects");
                    Globals_Game.RemoveObserver(client);
                    client.conn = null;
                    clientConnections.Remove(conn);

                    client.alg = null;
                    conn.Disconnect("Disconnect");
                }
            }
        }
示例#15
0
        public static bool ProcessLogIn(global::ProtoMessage.ProtoLogIn login, global::ProtoMessage.Client c, bool isPCL)
        {
            Contract.Requires(c != null && login != null);
            if (!VerifyUser(c.username, login.userSalt))
            {
                return(false);
            }
            try
            {
                if (login.Key != null)
                {
                    byte[] key = rsa.Decrypt(login.Key, false);
                    // Key must be non-null and long enough

                    if (key == null || key.Length < 5)
                    {
                        return(false);
                    }
                    c.alg = new NetAESEncryption(Globals_Server.server, key, 0, key.Length);
                }
                else
                {
#if ALLOW_UNENCRYPT
                    c.alg = null;
#else
                    return(false);
#endif
                }
                global::ProtoMessage.ProtoClient clientDetails = new global::ProtoMessage.ProtoClient(c);
                clientDetails.ActionType   = global::ProtoMessage.Actions.LogIn;
                clientDetails.ResponseType = global::ProtoMessage.DisplayMessages.LogInSuccess;
                Server.SendViaProto(clientDetails, c.conn, true, c.alg);
                Globals_Game.RegisterObserver(c);
                return(true);
            }
            catch (Exception e)
            {
#if DEBUG
                Console.WriteLine("Failure during decryption: " + e.GetType() + " " + e.Message + ";" + e.StackTrace);
#endif
                return(false);
            }
        }
示例#16
0
        /// <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 SpyArmyTest(TestClient testClient, string charID, string targetID)
        {
            testClient.SpyOnArmy(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;
            }
            Character spy    = Globals_Game.getCharFromID(charID);
            Army      target = null;

            Globals_Game.armyMasterList.TryGetValue(targetID, out target);
            if (spy == null || target == null)
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericCharacterUnidentified, response.ResponseType);
                return;
            }
            Client client = Globals_Server.Clients[testClient.playerID];

            if (spy.GetPlayerCharacter() != client.myPlayerCharacter)
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericUnauthorised, response.ResponseType);
                return;
            }
            if (spy.location != target.GetLocation())
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericNotInSameFief, response.ResponseType);
                return;
            }
            if (!(spy.days >= 10))
            {
                Assert.AreEqual(DisplayMessages.ErrorGenericNotEnoughDays, response.ResponseType);
                return;
            }
        }
示例#17
0
        /// <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);
        }
示例#18
0
        public void Listen()
        {
            while (server.Status == NetPeerStatus.Running && !ctSource.Token.IsCancellationRequested)
            {
                NetIncomingMessage im;
                WaitHandle.WaitAny(new WaitHandle[] { server.MessageReceivedEvent, ctSource.Token.WaitHandle });
                while ((im = server.ReadMessage()) != null && !ctSource.Token.IsCancellationRequested)
                {
                    if (im.SenderConnection != null)
                    {
                        Globals_Server.logEvent("Recieved: " + im.MessageType.ToString() + " | " + im.SenderConnection.RemoteEndPoint.ToString());
                    }
                    else
                    {
                        Globals_Server.logEvent("Recieved: " + im.MessageType.ToString() + " | NULL");
                    }

                    switch (im.MessageType)
                    {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                        Globals_Server.logError("Recieved warning message: " + im.ReadString());
                        break;

                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.Data:
                    {
#if DEBUG
                        //Console.WriteLine("SERVER: recieved data message");
#endif
                        if (!clientConnections.ContainsKey(im.SenderConnection))
                        {
                            //error
                            im.SenderConnection.Disconnect("Not recognised");
                            return;
                        }
                        Client c = clientConnections[im.SenderConnection];
                        if (c.alg != null)
                        {
                            im.Decrypt(c.alg);
                        }
                        ProtoMessage m = null;
                        using (MemoryStream ms = new MemoryStream(im.Data))
                        {
                            try
                            {
                                m = Serializer.DeserializeWithLengthPrefix <ProtoMessage>(ms, PrefixStyle.Fixed32);
                            }
                            catch (Exception e)
                            {
                                NetOutgoingMessage errorMessage = server.CreateMessage(
                                    "Failed to deserialise message. The message may be incorrect, or the decryption may have failed.");
                                if (c.alg != null)
                                {
                                    errorMessage.Encrypt(c.alg);
                                }
                                server.SendMessage(errorMessage, im.SenderConnection,
                                                   NetDeliveryMethod.ReliableOrdered);
                                Globals_Server.logError("Failed to deserialize message for client: " + c.username);
                            }
                        }
                        if (m == null)
                        {
                            string error = "Recieved null message from " + im.SenderEndPoint.ToString();
                            if (clientConnections.ContainsKey(im.SenderConnection))
                            {
                                error += ", recognised client " + clientConnections[im.SenderConnection];
                            }
                            else
                            {
                                error += ", unrecognised client (possible ping)";
                            }
                            error += ". Data: " + im.ReadString();
                            Globals_Server.logError(error);
                            break;
                        }

                        if (m.ActionType == Actions.LogIn)
                        {
                            ProtoLogIn login = m as ProtoLogIn;
                            if (login == null)
                            {
                                im.SenderConnection.Disconnect("Received blank login message.");
                                return;
                            }
                            lock (ServerLock)
                            {
                                if (LogInManager.VerifyUser(c.username, login.userSalt))
                                {
                                    if (LogInManager.ProcessLogIn(login, c))
                                    {
                                        string log = c.username + " logs in from " + im.SenderEndPoint.ToString();
                                        Globals_Server.logEvent(log);
                                    }
                                }
                                else
                                {
                                    ProtoMessage reply = new ProtoMessage
                                    {
                                        ActionType   = Actions.LogIn,
                                        ResponseType = DisplayMessages.LogInFail
                                    };
                                    Server.SendViaProto(reply, c.conn, c.alg);
                                    //reply = new ProtoMessage {
                                    //    ActionType = Actions.Update,
                                    //    ResponseType = DisplayMessages.Error
                                    //};
                                    //Server.SendViaProto(reply, c.conn, c.alg);
                                    im.SenderConnection.Disconnect("Authentication Fail");
                                    Globals_Server.logEvent("Wrong Password, disconnecting user.");
                                }
                            }
                        }
                        // temp for testing, should validate connection first
                        else if (clientConnections.ContainsKey(im.SenderConnection))
                        {
                            if (Globals_Game.IsObserver(c))
                            {
                                ProcessMessage(m, im.SenderConnection);
                                ProtoClient clientDetails = new ProtoClient(c);
                                clientDetails.ActionType   = Actions.Update;
                                clientDetails.ResponseType = DisplayMessages.Success;
                                SendViaProto(clientDetails, im.SenderConnection, c.alg);
                            }
                            else
                            {
                                im.SenderConnection.Disconnect("Not logged in- Disconnecting");
                            }
                        }
                    }
                    break;

                    case NetIncomingMessageType.StatusChanged:
                        byte stat = im.ReadByte();
                        NetConnectionStatus status = NetConnectionStatus.None;
                        if (Enum.IsDefined(typeof(NetConnectionStatus), Convert.ToInt32(stat)))
                        {
                            status = (NetConnectionStatus)stat;
                        }
                        else
                        {
                            Globals_Server.logError("Failure to parse byte " + stat + " to NetConnectionStatus for endpoint " + im.ReadIPEndPoint());
                        }
                        Globals_Server.logEvent("\tStatus is now: " + status);
                        if (status == NetConnectionStatus.Disconnected)
                        {
                            string reason = im.ReadString();
                            if (reason == null)
                            {
                                reason = "Unknown";
                            }
                            Globals_Server.logEvent(im.SenderConnection.RemoteEndPoint.ToString() + " has disconnected. Reason: " + reason);
                            if (clientConnections.ContainsKey(im.SenderConnection))
                            {
                                Disconnect(im.SenderConnection);
                            }
                        }
                        break;

                    case NetIncomingMessageType.ConnectionApproval:
                    {
                        string senderID = im.ReadString();
                        string text     = im.ReadString();
                        Client client;
                        Globals_Server.Clients.TryGetValue(senderID, out client);
                        if (client != null)
                        {
                            ProtoLogIn logIn;
                            //ProtoMessage logIn;
                            if (!LogInManager.AcceptConnection(client, text, out logIn))
                            {
                                im.SenderConnection.Deny("User not recognised.");
                            }
                            else
                            {
                                ProtoMessage temp = logIn;

                                NetOutgoingMessage msg = server.CreateMessage();
                                MemoryStream       ms  = new MemoryStream();
                                // Include X509 certificate as bytes for client to validate
                                //Serializer.SerializeWithLengthPrefix<ProtoLogIn>(ms, logIn, PrefixStyle.Fixed32);
                                Serializer.SerializeWithLengthPrefix <ProtoMessage>(ms, temp, PrefixStyle.Fixed32);
                                msg.Write(ms.GetBuffer());

                                clientConnections.Add(im.SenderConnection, client);
                                client.conn = im.SenderConnection;
                                im.SenderConnection.Approve(msg);
                                //server.FlushSendQueue();
                                Globals_Server.logEvent("Accepted connection from " + client.username + " | " + senderID + " | " + text);
                            }
                        }
                        else
                        {
                            im.SenderConnection.Deny("Username unrecognised.");
                        }
                        server.FlushSendQueue();
                    }

                    break;

                    case NetIncomingMessageType.ConnectionLatencyUpdated:
                        Globals_Server.logEvent("LATENCY: Still getting these.");
                        break;

                    default:
                        Globals_Server.logError("Received unrecognised incoming message type: " + im.MessageType);
                        break;
                    }
                    server.Recycle(im);
                }
            }
            Globals_Server.logEvent("Server listening thread exits.");
        }
示例#19
0
        /// <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);
        }
示例#20
0
 /// <summary>
 /// Respond to ransom demands
 /// </summary>
 /// <param name="paid">Whether or not ransom is to be paid</param>
 /// <returns>Bool indicating success</returns>
 public bool RansomResponse(bool paid, out ProtoMessage error)
 {
     error = null;
     // Check if type is ransom
     if (this.type.Equals("ransom"))
     {
         // Check if already replied
         if (replied)
         {
             // Already replied
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.RansomRepliedAlready;
             return(false);
         }
         Character       captive = null;
         PlayerCharacter captor;
         PlayerCharacter captiveHeadOfHousehold;
         // Confirm captive is still alive and being held
         foreach (string persona in personae)
         {
             string[] split = persona.Split(new char[] { '|' });
             if (split[1].Equals("Captive"))
             {
                 captive = Globals_Game.getCharFromID(split[0]);
             }
         }
         if (captive == null)
         {
             // Captive does not exist- error
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.ErrorGenericCharacterUnidentified;
             Globals_Server.logError("Captive unidentified in JEntry: " + this.jEntryID);
             return(false);
         }
         else if (!captive.isAlive)
         {
             // Captive is dead
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.RansomCaptiveDead;
             return(false);
         }
         captor = Globals_Game.getCharFromID(captive.captorID) as PlayerCharacter;
         if (captor == null)
         {
             // Captive does not have a captor
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.NotCaptive;
             return(false);
         }
         captiveHeadOfHousehold = captive.GetPlayerCharacter();
         if (captiveHeadOfHousehold == null)
         {
             // Captive is not an employee, family member or player character
             Globals_Server.logError("Captive has no PlayerCharacter: " + captive.charID);
             error = new ProtoMessage();
             error.ResponseType = DisplayMessages.ErrorGenericCharacterUnidentified;
             return(false);
         }
         if (paid)
         {
             // Get ransom amount
             uint ransom = 0;
             if (!UInt32.TryParse(entryDetails.MessageFields[1], out ransom))
             {
                 // Error parsing to int
                 Globals_Server.logError("Could not parse ransom to uint in JEntry: " + jEntryID);
                 error = new ProtoMessage();
                 error.ResponseType = DisplayMessages.ErrorGenericMessageInvalid;
                 return(false);
             }
             else
             {
                 // Check captive's head of household has the funds to release
                 if (captiveHeadOfHousehold.GetHomeFief().GetAvailableTreasury(false) >= ransom)
                 {
                     if (!captiveHeadOfHousehold.GetHomeFief().TreasuryTransfer(captor.GetHomeFief(), (Int32)ransom, out error))
                     {
                         return(false);
                     }
                     else
                     {
                         // Release captive
                         captor.ReleaseCaptive(captive);
                         replied = true;
                         Globals_Game.UpdatePlayer(captor.playerID, DisplayMessages.RansomPaid, new string[] { captive.firstName + " " + captive.familyName });
                         return(true);
                     }
                 }
                 else
                 {
                     // Insufficient funds
                     error = new ProtoMessage();
                     error.ResponseType = DisplayMessages.ErrorGenericInsufficientFunds;
                     return(false);
                 }
             }
         }
         // If not paying ransom, inform captor
         else
         {
             // Create journal entry and update captor
             string[]     newPersonae   = new string[] { captive.charID + "|Captive", captor.charID + "|Captor", captiveHeadOfHousehold.charID + "|HeadOfCaptiveFamily" };
             ProtoMessage deniedMessage = new ProtoMessage();
             deniedMessage.ResponseType  = DisplayMessages.RansonDenied;
             deniedMessage.MessageFields = new string[] { captive.firstName + " " + captive.familyName, captor.firstName + " " + captor.familyName, captiveHeadOfHousehold.firstName + " " + captiveHeadOfHousehold.familyName };
             Globals_Game.UpdatePlayer(captor.playerID, deniedMessage);
             JournalEntry ransomDenied = new JournalEntry(Globals_Game.GetNextJournalEntryID(), Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason, newPersonae, "ransomDenied", deniedMessage);
             Globals_Game.AddPastEvent(ransomDenied);
             replied = true;
             return(true);
         }
     }
     else
     {
         // Not a ransom
         error = new ProtoMessage();
         error.ResponseType = DisplayMessages.EntryNotRansom;
         return(false);
     }
 }
示例#21
0
 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();
 }
示例#22
0
        /// <summary>
        /// Processes the actions involved with an engagement
        /// </summary>
        /// <returns>bool indicating whether engagement was processed successfully</returns>
        public bool ProcessEngagement()
        {
            bool success = false;

            // get interested parties
            PlayerCharacter headOfFamilyBride = null;
            PlayerCharacter headOfFamilyGroom = null;
            Character       bride             = null;
            Character       groom             = null;

            for (int i = 0; i < this.personae.Length; i++)
            {
                string   thisPersonae      = this.personae[i];
                string[] thisPersonaeSplit = thisPersonae.Split('|');

                switch (thisPersonaeSplit[1])
                {
                case "headOfFamilyBride":
                    headOfFamilyBride = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    break;

                case "headOfFamilyGroom":
                    headOfFamilyGroom = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    break;

                case "bride":
                    bride = Globals_Game.npcMasterList[thisPersonaeSplit[0]];
                    break;

                case "groom":
                    if (Globals_Game.pcMasterList.ContainsKey(thisPersonaeSplit[0]))
                    {
                        groom = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    }
                    else if (Globals_Game.npcMasterList.ContainsKey(thisPersonaeSplit[0]))
                    {
                        groom = Globals_Game.npcMasterList[thisPersonaeSplit[0]];
                    }
                    break;

                default:
                    break;
                }
            }

            // ID
            uint replyID = Globals_Game.GetNextJournalEntryID();

            // date
            uint year   = Globals_Game.clock.currentYear;
            byte season = Globals_Game.clock.currentSeason;

            if (season == 3)
            {
                season = 0;
                year++;
            }
            else
            {
                season++;
            }

            // personae
            string headOfFamilyBrideEntry = headOfFamilyBride.charID + "|headOfFamilyBride";
            string headOfFamilyGroomEntry = headOfFamilyGroom.charID + "|headOfFamilyGroom";
            string thisBrideEntry         = bride.charID + "|bride";
            string thisGroomEntry         = groom.charID + "|groom";

            string[] marriagePersonae = new string[] { headOfFamilyGroomEntry, headOfFamilyBrideEntry, thisBrideEntry, thisGroomEntry };

            // type
            string type = "marriage";

            // create and add a marriage entry to the scheduledEvents journal
            JournalEntry marriageEntry = new JournalEntry(replyID, year, season, marriagePersonae, type, null);

            success = Globals_Game.AddScheduledEvent(marriageEntry);

            // show bride and groom as engaged
            if (success)
            {
                bride.fiancee = groom.charID;
                groom.fiancee = bride.charID;
            }

            return(success);
        }
示例#23
0
        // TODO I suspect there may be issues with this if any of the characters die. Test.
        /// <summary>
        /// Allows a character to reply to a marriage proposal
        /// </summary>
        /// <returns>bool indicating whether reply was processed successfully</returns>
        /// <param name="proposalAccepted">bool indicating whether proposal accepted</param>
        public bool ReplyToProposal(bool proposalAccepted)
        {
            bool success = true;

            string[] replyFields = new string[4];
            // get interested parties
            PlayerCharacter headOfFamilyBride = null;
            PlayerCharacter headOfFamilyGroom = null;
            Character       bride             = null;
            Character       groom             = null;

            for (int i = 0; i < this.personae.Length; i++)
            {
                string   thisPersonae      = this.personae[i];
                string[] thisPersonaeSplit = thisPersonae.Split('|');

                switch (thisPersonaeSplit[1])
                {
                case "headOfFamilyBride":
                    headOfFamilyBride = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    break;

                case "headOfFamilyGroom":
                    headOfFamilyGroom = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    break;

                case "bride":
                    bride = Globals_Game.npcMasterList[thisPersonaeSplit[0]];
                    break;

                case "groom":
                    if (Globals_Game.pcMasterList.ContainsKey(thisPersonaeSplit[0]))
                    {
                        groom = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    }
                    else if (Globals_Game.npcMasterList.ContainsKey(thisPersonaeSplit[0]))
                    {
                        groom = Globals_Game.npcMasterList[thisPersonaeSplit[0]];
                    }
                    break;

                default:
                    break;
                }
            }

            // ID
            uint replyID = 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(headOfFamilyBride.charID + "|headOfFamilyBride");
            tempPersonae.Add(headOfFamilyGroom.charID + "|headOfFamilyGroom");
            tempPersonae.Add(bride.charID + "|bride");
            tempPersonae.Add(groom.charID + "|groom");
            if (proposalAccepted)
            {
                tempPersonae.Add("all|all");
            }
            string[] myReplyPersonae = tempPersonae.ToArray();

            // type
            string type = "";

            if (proposalAccepted)
            {
                type = "proposalAccepted";
            }
            else
            {
                type = "proposalRejected";
            }

            // description
            replyFields[0] = groom.firstName + " " + groom.familyName;
            replyFields[1] = bride.firstName + " " + bride.familyName;

            if (proposalAccepted)
            {
                replyFields[2] = "ACCEPTED";
            }
            else
            {
                replyFields[2] = "REJECTED";
            }
            replyFields[3] = headOfFamilyBride.firstName + " " + headOfFamilyBride.familyName;

            ProtoMessage proposalReply = new ProtoMessage();

            proposalReply.MessageFields = replyFields;
            proposalReply.ResponseType  = DisplayMessages.JournalProposalReply;
            // create and send a proposal reply (journal entry)
            JournalEntry myProposalReply = new JournalEntry(replyID, year, season, myReplyPersonae, type, proposalReply, null);

            success = Globals_Game.AddPastEvent(myProposalReply);

            if (success)
            {
                string[] newFields = new string[this.entryDetails.MessageFields.Length + 2];
                Array.Copy(this.entryDetails.MessageFields, newFields, this.entryDetails.MessageFields.Length);
                newFields[newFields.Length - 1] = Globals_Game.clock.seasons[season] + ", " + year;
                this.entryDetails.MessageFields = newFields;
                this.replied = true;
                // mark proposal as replied
                if (proposalAccepted)
                {
                    this.entryDetails.MessageFields[this.entryDetails.MessageFields.Length - 2] = "ACCEPTED";
                }
                else
                {
                    this.entryDetails.MessageFields[this.entryDetails.MessageFields.Length - 2] = "REJECTED";
                }

                // if accepted, process engagement
                if (proposalAccepted)
                {
                    myProposalReply.ProcessEngagement();
                }
            }

            return(success);
        }
示例#24
0
        public void Listen()
        {
            while (server.Status == NetPeerStatus.Running && !ctSource.Token.IsCancellationRequested)
            {
                NetIncomingMessage im;
                WaitHandle.WaitAny(new WaitHandle[] { server.MessageReceivedEvent, ctSource.Token.WaitHandle });
                while ((im = server.ReadMessage()) != null && !ctSource.Token.IsCancellationRequested)
                {
                    switch (im.MessageType)
                    {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                        Globals_Server.logError("Recieved warning message: " + im.ReadString());
                        break;

                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.Data:
                    {
#if DEBUG
                        Console.WriteLine("SERVER: recieved data message");
#endif
                        if (!clientConnections.ContainsKey(im.SenderConnection))
                        {
                            //error
                            im.SenderConnection.Disconnect("Not recognised");
                            return;
                        }
                        Client c = clientConnections[im.SenderConnection];
                        if (c.alg != null)
                        {
                            im.Decrypt(c.alg);
                        }
                        ProtoMessage m = null;
                        //global::ProtoMessage.ProtoMessage y = null;
                        using (MemoryStream ms = new MemoryStream(im.Data))
                        {
                            try
                            {
                                //y = Serializer.DeserializeWithLengthPrefix<global::ProtoMessage.ProtoMessage>(ms,
                                //PrefixStyle.Fixed32);
                                m = Serializer.DeserializeWithLengthPrefix <ProtoMessage>(ms, PrefixStyle.Fixed32);
                            }
                            catch (Exception e)
                            {
                                NetOutgoingMessage errorMessage = server.CreateMessage(
                                    "Failed to deserialise message. The message may be incorrect, or the decryption may have failed.");
                                if (c.alg != null)
                                {
                                    errorMessage.Encrypt(c.alg);
                                }
                                server.SendMessage(errorMessage, im.SenderConnection,
                                                   NetDeliveryMethod.ReliableOrdered);
                                Globals_Server.logError("Failed to deserialize message for client: " + c.username);
                            }
                        }
                        if (m == null /*&& y == null*/)
                        {
                            string error = "Recieved null message from " + im.SenderEndPoint.ToString();
                            if (clientConnections.ContainsKey(im.SenderConnection))
                            {
                                error += ", recognised client " + clientConnections[im.SenderConnection];
                            }
                            else
                            {
                                error += ", unrecognised client (possible ping)";
                            }
                            error += ". Data: " + im.ReadString();
                            Globals_Server.logError(error);
                            break;
                        }

                        if (m.ActionType == Actions.LogIn)
                        {
                            ProtoLogIn login = m as ProtoLogIn;
                            if (login == null)
                            {
                                im.SenderConnection.Disconnect("Not login");
                                return;
                            }
                            lock (ServerLock)
                            {
                                if (LogInManager.VerifyUser(c.username, login.userSalt))
                                {
                                    if (LogInManager.ProcessLogIn(login, c))
                                    {
                                        string log = c.username + " logs in from " + im.SenderEndPoint.ToString();
                                        Globals_Server.logEvent(log);
                                    }
                                }
                                else
                                {
                                    ProtoMessage reply = new ProtoMessage
                                    {
                                        ActionType   = Actions.LogIn,
                                        ResponseType = DisplayMessages.LogInFail
                                    };
                                    im.SenderConnection.Disconnect("Authentication Fail");
                                }
                            }
                        }
                        // temp for testing, should validate connection first
                        else if (clientConnections.ContainsKey(im.SenderConnection))
                        {
                            if (Globals_Game.IsObserver(c))
                            {
                                ProcessMessage(m, im.SenderConnection);
                                ProtoClient clientDetails = new ProtoClient(c);
                                clientDetails.ActionType = Actions.Update;
                                SendViaProto(clientDetails, im.SenderConnection, c.alg);
                            }
                            else
                            {
                                im.SenderConnection.Disconnect("Not logged in- Disconnecting");
                            }
                        }

                        /*//IF Y ACTION
                         *  if (y.ActionType == global::ProtoMessage.Actions.LogIn)
                         *  {
                         *      global::ProtoMessage.Client forCheck = new global::ProtoMessage.Client(c.username, c.myPlayerCharacter.playerID);
                         *      global::ProtoMessage.ProtoLogIn login = y as global::ProtoMessage.ProtoLogIn;
                         *      if (login == null)
                         *      {
                         *          im.SenderConnection.Disconnect("Not login");
                         *          return;
                         *      }
                         *      lock (ServerLock)
                         *      {
                         *          if (LogInManager.VerifyUser(c.username, login.userSalt))
                         *          {
                         *              if (LogInManager.ProcessLogIn(login, forCheck, true))
                         *              {
                         *                  string log = c.username + " logs in from " + im.SenderEndPoint.ToString();
                         *                  Globals_Server.logEvent(log);
                         *              }
                         *          }
                         *          else
                         *          {
                         *              ProtoMessage reply = new ProtoMessage
                         *              {
                         *                  ActionType = Actions.LogIn,
                         *                  ResponseType = DisplayMessages.LogInFail
                         *              };
                         *              im.SenderConnection.Disconnect("Authentication Fail");
                         *          }
                         *      }
                         *  }
                         *  // temp for testing, should validate connection first
                         *  else if (clientConnections.ContainsKey(im.SenderConnection))
                         *  {
                         *      if (Globals_Game.IsObserver(c))
                         *      {
                         *          ProcessMessage(y, im.SenderConnection);
                         *          ProtoClient clientDetails = new ProtoClient(c);
                         *          clientDetails.ActionType = Actions.Update;
                         *          SendViaProto(clientDetails, im.SenderConnection, c.alg);
                         *      }
                         *      else
                         *      {
                         *          im.SenderConnection.Disconnect("Not logged in- Disconnecting");
                         *      }
                         *  }*/
                    }
                    break;

                    case NetIncomingMessageType.StatusChanged:
                        byte stat = im.ReadByte();
                        NetConnectionStatus status = NetConnectionStatus.None;
                        if (Enum.IsDefined(typeof(NetConnectionStatus), Convert.ToInt32(stat)))
                        {
                            status = (NetConnectionStatus)stat;
                        }
                        else
                        {
                            Globals_Server.logError("Failure to parse byte " + stat + " to NetConnectionStatus for endpoint " + im.ReadIPEndPoint());
                        }
                        if (status == NetConnectionStatus.Disconnected)
                        {
                            if (clientConnections.ContainsKey(im.SenderConnection))
                            {
                                Disconnect(im.SenderConnection);
                            }
                        }
                        break;

                    case NetIncomingMessageType.ConnectionApproval:
                    {
                        string senderID = im.ReadString();
                        string text     = im.ReadString();
                        Client client;
                        Globals_Server.Clients.TryGetValue(senderID, out client);
                        if (client != null)
                        {
                            ProtoLogIn logIn;
                            if (!LogInManager.AcceptConnection(client, text, out logIn))
                            {
                                im.SenderConnection.Deny();
                            }
                            else
                            {
                                NetOutgoingMessage msg = server.CreateMessage();
                                MemoryStream       ms  = new MemoryStream();
                                // Include X509 certificate as bytes for client to validate
                                Serializer.SerializeWithLengthPrefix <ProtoLogIn>(ms, logIn, PrefixStyle.Fixed32);
                                msg.Write(ms.GetBuffer());
                                clientConnections.Add(im.SenderConnection, client);
                                client.conn = im.SenderConnection;
                                im.SenderConnection.Approve(msg);
                                server.FlushSendQueue();
                                Globals_Server.logEvent("Accepted connection from " + client.username);
                            }
                        }
                        else
                        {
                            im.SenderConnection.Deny("unrecognised");
                        }
                    }

                    break;

                    case NetIncomingMessageType.ConnectionLatencyUpdated:
                        break;

                    default:
                        Globals_Server.logError("Received unrecognised incoming message type: " + im.MessageType);
                        break;
                    }
                    server.Recycle(im);
                }
            }
#if DEBUG
            Globals_Server.logEvent("Server listening thread exits");
#endif
        }
示例#25
0
        /// <summary>
        /// Implements the processes involved in a battle between two armies in the field
        /// </summary>
        /// <returns>bool indicating whether attacking army is victorious</returns>
        /// <remarks>
        /// Predicate: assumes attacker has sufficient days
        /// Predicate: assumes attacker has leader
        /// Predicate: assumes attacker in same fief as defender
        /// Predicate: assumes defender not besieged in keep
        /// Predicate: assumes attacker and defender not same army
        /// </remarks>
        /// <param name="attacker">The attacking army</param>
        /// <param name="defender">The defending army</param>
        /// <param name="circumstance">string indicating circumstance of battle</param>
        public static bool GiveBattle(Army attacker, Army defender, out ProtoBattle battleResults, string circumstance = "battle")
        {
            Contract.Requires(attacker != null && defender != null && circumstance != null);
            battleResults = new ProtoBattle();
            bool attackerVictorious = false;
            bool battleHasCommenced = false;
            bool attackerLeaderDead = false;
            bool defenderLeaderDead = false;
            // check if losing army has disbanded
            bool attackerDisbanded = false;
            bool defenderDisbanded = false;

            bool siegeRaised = false;

            uint[]   battleValues      = new uint[2];
            double[] casualtyModifiers = new double[2];
            double   statureChange     = 0;

            // if applicable, get siege
            Siege  thisSiege   = null;
            string thisSiegeID = defender.CheckIfBesieger();

            if (!String.IsNullOrWhiteSpace(thisSiegeID))
            {
                // get siege
                thisSiege = Globals_Game.siegeMasterList[thisSiegeID];
            }

            // get starting troop numbers
            uint attackerStartTroops = attacker.CalcArmySize();
            uint defenderStartTroops = defender.CalcArmySize();
            uint attackerCasualties  = 0;
            uint defenderCasualties  = 0;

            // get leaders
            Character attackerLeader = attacker.GetLeader();
            Character defenderLeader = defender.GetLeader();

            // if(attackerLeader!=null) {
            battleResults.attackerLeader = attackerLeader.firstName + " " + attackerLeader.familyName;
            //  }
            //  if(defenderLeader!=null) {
            battleResults.defenderLeader = defenderLeader.firstName + " " + defenderLeader.familyName;
            //   }

            battleResults.attackerOwner  = attacker.GetOwner().firstName + "  " + attacker.GetOwner().familyName;
            battleResults.defenderOwner  = defender.GetOwner().firstName + " " + defender.GetOwner().familyName;
            battleResults.battleLocation = attacker.GetLocation().id;
            // introductory text for message
            switch (circumstance)
            {
            case "pillage":
                battleResults.circumstance = 1;
                break;

            case "siege":
                battleResults.circumstance = 2;
                break;

            default:
                battleResults.circumstance = 0;
                break;
            }

            // get battle values for both armies
            battleValues = attacker.CalculateBattleValues(defender);

            // check if attacker has managed to bring defender to battle
            // case 1: defending army sallies during siege to attack besieger = battle always occurs
            if (circumstance.Equals("siege"))
            {
                battleHasCommenced = true;
            }
            // case 2: defending militia attacks pillaging army during pollage = battle always occurs
            else if (circumstance.Equals("pillage"))
            {
                battleHasCommenced = true;
            }
            // case 3: defender aggression and combatOdds allows battle
            else if (defender.aggression != 0)
            {
                if (defender.aggression == 1)
                {
                    // get odds
                    int battleOdds = Battle.GetBattleOdds(attacker, defender);

                    // if odds OK, give battle
                    if (battleOdds <= defender.combatOdds)
                    {
                        battleHasCommenced = true;
                    }

                    // if not, check for battle
                    else
                    {
                        battleHasCommenced = Battle.BringToBattle(battleValues[0], battleValues[1], circumstance);

                        if (!battleHasCommenced)
                        {
                            defender.ProcessRetreat(1);
                        }
                    }
                }

                else
                {
                    battleHasCommenced = true;
                }
            }

            // otherwise, check to see if the attacker can bring the defender to battle
            else
            {
                battleHasCommenced = Battle.BringToBattle(battleValues[0], battleValues[1], circumstance);
                if (!battleHasCommenced)
                {
                    defender.ProcessRetreat(1);
                }
            }
            battleResults.battleTookPlace = battleHasCommenced;
            if (battleHasCommenced)
            {
                List <string> disbandedArmies = new List <string>();
                List <string> retreatedArmies = new List <string>();
                List <string> deadCharacters  = new List <string>();
                // WHO HAS WON?
                // calculate if attacker has won
                attackerVictorious = Battle.DecideBattleVictory(battleValues[0], battleValues[1]);

                // UPDATE STATURE
                if (attackerVictorious)
                {
                    statureChange = 0.8 * (defender.CalcArmySize() / Convert.ToDouble(10000));
                    battleResults.statureChangeAttacker = statureChange;
                    attacker.GetOwner().AdjustStatureModifier(statureChange);
                    statureChange = -0.5 * (attacker.CalcArmySize() / Convert.ToDouble(10000));
                    battleResults.statureChangeDefender = statureChange;
                    defender.GetOwner().AdjustStatureModifier(statureChange);
                }
                else
                {
                    statureChange = 0.8 * (attacker.CalcArmySize() / Convert.ToDouble(10000));
                    battleResults.statureChangeDefender = statureChange;
                    defender.GetOwner().AdjustStatureModifier(statureChange);
                    statureChange = -0.5 * (defender.CalcArmySize() / Convert.ToDouble(10000));
                    battleResults.statureChangeAttacker = statureChange;
                    attacker.GetOwner().AdjustStatureModifier(statureChange);
                }

                // CASUALTIES
                // calculate troop casualties for both sides
                casualtyModifiers = Battle.CalculateBattleCasualties(attackerStartTroops, defenderStartTroops, battleValues[0], battleValues[1], attackerVictorious);


                uint totalAttackTroopsLost = 0;
                uint totalDefendTroopsLost = 0;

                // if losing side sustains >= 50% casualties, disbands
                if (attackerVictorious)
                {
                    // either indicate losing army to be disbanded
                    if (casualtyModifiers[1] >= 0.5)
                    {
                        defenderDisbanded = true;
                        disbandedArmies.Add(defender.owner);
                        totalDefendTroopsLost = defender.CalcArmySize();
                    }
                    // OR apply troop casualties to losing army
                    else
                    {
                        totalDefendTroopsLost = defender.ApplyTroopLosses(casualtyModifiers[1]);
                    }

                    // apply troop casualties to winning army
                    totalAttackTroopsLost = attacker.ApplyTroopLosses(casualtyModifiers[0]);
                }
                else
                {
                    if (casualtyModifiers[0] >= 0.5)
                    {
                        attackerDisbanded = true;
                        disbandedArmies.Add(attacker.owner);
                        totalAttackTroopsLost = attacker.CalcArmySize();
                    }
                    else
                    {
                        totalAttackTroopsLost = attacker.ApplyTroopLosses(casualtyModifiers[0]);
                    }

                    totalDefendTroopsLost = defender.ApplyTroopLosses(casualtyModifiers[1]);
                }
                battleResults.attackerCasualties = totalAttackTroopsLost;
                battleResults.defenderCasualties = totalDefendTroopsLost;
                // UPDATE TOTAL SIEGE LOSSES, if appropriate
                // NOTE: the defender in this battle is the attacker in the siege and v.v.
                if (thisSiege != null)
                {
                    // update total siege attacker (defender in this battle) losses
                    thisSiege.totalCasualtiesAttacker += Convert.ToInt32(totalDefendTroopsLost);

                    // update total siege defender (attacker in this battle) losses
                    if (circumstance.Equals("siege"))
                    {
                        thisSiege.totalCasualtiesDefender += Convert.ToInt32(totalAttackTroopsLost);
                    }
                }

                // get casualty figures (for message)
                if (!attackerDisbanded)
                {
                    // get attacker casualties
                    attackerCasualties = totalAttackTroopsLost;
                }
                if (!defenderDisbanded)
                {
                    // get defender casualties
                    defenderCasualties = totalDefendTroopsLost;
                }

                // DAYS
                // adjust days
                // NOTE: don't adjust days if is a siege (will be deducted elsewhere)
                if (!circumstance.Equals("siege"))
                {
                    if (attackerLeader != null)
                    {
                        attackerLeader.AdjustDays(1);
                    }
                    // need to check for defender having no leader
                    if (defenderLeader != null)
                    {
                        defenderLeader.AdjustDays(1);
                    }
                    else
                    {
                        defender.days -= 1;
                    }
                }

                // RETREATS
                // create array of armies (for easy processing)
                Army[] bothSides = { attacker, defender };

                // check if either army needs to retreat
                int[] retreatDistances = Battle.CheckForRetreat(attacker, defender, casualtyModifiers[0], casualtyModifiers[1], attackerVictorious);

                // if is pillage or siege, attacking army (the fief's army) doesn't retreat
                // if is pillage, the defending army (the pillagers) always retreats if has lost
                if (circumstance.Equals("pillage") || circumstance.Equals("siege"))
                {
                    retreatDistances[0] = 0;
                }

                if (circumstance.Equals("pillage"))
                {
                    if (attackerVictorious)
                    {
                        retreatDistances[1] = 1;
                    }
                }

                // if have retreated, perform it
                for (int i = 0; i < retreatDistances.Length; i++)
                {
                    if (retreatDistances[i] > 0)
                    {
                        bothSides[i].ProcessRetreat(retreatDistances[i]);
                    }
                }
                // If attacker has retreated add to retreat list
                if (retreatDistances[0] > 0)
                {
                    retreatedArmies.Add(battleResults.attackerOwner);
                }
                // If defender retreated add to retreat list
                if (retreatDistances[1] > 0)
                {
                    retreatedArmies.Add(battleResults.defenderOwner);
                }
                // PC/NPC INJURIES/DEATHS
                // check if any PCs/NPCs have been wounded or killed
                bool characterDead = false;

                // 1. ATTACKER
                uint friendlyBV = battleValues[0];
                uint enemyBV    = battleValues[1];

                // if army leader a PC, check entourage
                if (attackerLeader is PlayerCharacter)
                {
                    for (int i = 0; i < (attackerLeader as PlayerCharacter).myNPCs.Count; i++)
                    {
                        if ((attackerLeader as PlayerCharacter).myNPCs[i].inEntourage)
                        {
                            characterDead = (attackerLeader as PlayerCharacter).myNPCs[i].CalculateCombatInjury(casualtyModifiers[0]);
                        }

                        // process death, if applicable
                        if (characterDead)
                        {
                            (attackerLeader as PlayerCharacter).myNPCs[i].ProcessDeath("injury");
                        }
                    }
                }

                // check army leader
                if (attackerLeader != null)
                {
                    attackerLeaderDead = attackerLeader.CalculateCombatInjury(casualtyModifiers[0]);
                }


                // process death, if applicable
                if (attackerLeaderDead)
                {
                    deadCharacters.Add(attackerLeader.firstName + " " + attackerLeader.familyName);
                    Character newLeader = null;

                    // if is pillage, do NOT elect new leader for attacking army
                    if (!circumstance.Equals("pillage"))
                    {
                        // if possible, elect new leader from entourage
                        if (attackerLeader is PlayerCharacter)
                        {
                            if ((attackerLeader as PlayerCharacter).myNPCs.Count > 0)
                            {
                                // get new leader
                                newLeader = (attackerLeader as PlayerCharacter).ElectNewArmyLeader();
                            }
                        }

                        // assign newLeader (can assign null leader if none found)
                        attacker.AssignNewLeader(newLeader);
                    }
                }
                else
                {
                    // if pillage, if fief's army loses, make sure bailiff always returns to keep
                    if (circumstance.Equals("pillage"))
                    {
                        if (!attackerVictorious)
                        {
                            attackerLeader.inKeep = true;
                        }
                    }
                }

                // 2. DEFENDER

                // need to check if defending army had a leader
                if (defenderLeader != null)
                {
                    // if army leader a PC, check entourage
                    if (defenderLeader is PlayerCharacter)
                    {
                        for (int i = 0; i < (defenderLeader as PlayerCharacter).myNPCs.Count; i++)
                        {
                            if ((defenderLeader as PlayerCharacter).myNPCs[i].inEntourage)
                            {
                                characterDead = (defenderLeader as PlayerCharacter).myNPCs[i].CalculateCombatInjury(casualtyModifiers[1]);
                            }

                            // process death, if applicable
                            if (characterDead)
                            {
                                (defenderLeader as PlayerCharacter).myNPCs[i].ProcessDeath("injury");
                            }
                        }
                    }

                    // check army leader
                    defenderLeaderDead = defenderLeader.CalculateCombatInjury(casualtyModifiers[1]);

                    // process death, if applicable
                    if (defenderLeaderDead)
                    {
                        deadCharacters.Add(defenderLeader.firstName + " " + defenderLeader.familyName);
                        Character newLeader = null;

                        // if possible, elect new leader from entourage
                        if (defenderLeader is PlayerCharacter)
                        {
                            if ((defenderLeader as PlayerCharacter).myNPCs.Count > 0)
                            {
                                // get new leader
                                newLeader = (defenderLeader as PlayerCharacter).ElectNewArmyLeader();
                            }
                        }

                        // assign newLeader (can assign null leader if none found)
                        defender.AssignNewLeader(newLeader);
                    }
                }

                battleResults.deaths          = deadCharacters.ToArray();
                battleResults.retreatedArmies = retreatedArmies.ToArray();

                battleResults.attackerVictorious = attackerVictorious;

                // check for SIEGE RELIEF
                if (thisSiege != null)
                {
                    battleResults.isSiege       = true;
                    battleResults.siegeBesieger = thisSiege.GetBesiegingPlayer().firstName + " " + thisSiege.GetBesiegingPlayer().familyName;
                    battleResults.siegeDefender = thisSiege.GetDefendingPlayer().firstName + " " + thisSiege.GetDefendingPlayer().familyName;
                    // attacker (relieving army) victory or defender (besieging army) retreat = relief
                    if ((attackerVictorious) || (retreatDistances[1] > 0))
                    {
                        // indicate siege raised
                        siegeRaised = true;
                        battleResults.siegeRaised = true;
                    }

                    // check to see if siege raised due to death of siege owner with no heir
                    else if ((defenderLeaderDead) && ((defenderLeader as PlayerCharacter) == thisSiege.GetBesiegingPlayer()))
                    {
                        // get siege owner's heir
                        Character thisHeir = (defenderLeader as PlayerCharacter).GetHeir();

                        if (thisHeir == null)
                        {
                            battleResults.DefenderDeadNoHeir = true;
                            // indicate siege raised
                            siegeRaised = true;
                        }
                    }
                }
            }

            // =================== construct and send JOURNAL ENTRY
            // ID
            uint entryID = Globals_Game.GetNextJournalEntryID();

            // personae
            // personae tags vary depending on circumstance
            string attackOwnTag  = "|attackerOwner";
            string attackLeadTag = "|attackerLeader";
            string defendOwnTag  = "|defenderOwner";
            string defendLeadTag = "|defenderLeader";

            if ((circumstance.Equals("pillage")) || (circumstance.Equals("siege")))
            {
                attackOwnTag  = "|sallyOwner";
                attackLeadTag = "|sallyLeader";
                defendOwnTag  = "|defenderAgainstSallyOwner";
                defendLeadTag = "|defenderAgainstSallyLeader";
            }
            List <string> tempPersonae = new List <string>();

            tempPersonae.Add(defender.GetOwner().charID + defendOwnTag);
            if (attackerLeader != null)
            {
                tempPersonae.Add(attackerLeader.charID + attackLeadTag);
            }
            if (defenderLeader != null)
            {
                tempPersonae.Add(defenderLeader.charID + defendLeadTag);
            }
            tempPersonae.Add(attacker.GetOwner().charID + attackOwnTag);
            tempPersonae.Add(attacker.GetLocation().owner.charID + "|fiefOwner");
            if ((!circumstance.Equals("pillage")) && (!circumstance.Equals("siege")))
            {
                tempPersonae.Add("all|all");
            }
            string[] battlePersonae = tempPersonae.ToArray();

            // location
            string battleLocation = attacker.GetLocation().id;


            // put together new journal entry
            JournalEntry battleResult = new JournalEntry(entryID, Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason, battlePersonae, "battle", battleResults, loc: battleLocation);

            // add new journal entry to pastEvents
            Globals_Game.AddPastEvent(battleResult);

            // display pop-up informational message
            battleResults.ActionType   = Actions.Update;
            battleResults.ResponseType = DisplayMessages.BattleResults;
            if (battleHasCommenced)
            {
                Globals_Game.UpdatePlayer(defender.GetOwner().playerID, DisplayMessages.BattleBringSuccess, new string[] { battleResults.attackerOwner });
            }
            else
            {
                Globals_Game.UpdatePlayer(defender.GetOwner().playerID, DisplayMessages.BattleBringFail, new string[] { battleResults.attackerOwner });
            }

            // end siege if appropriate
            if (siegeRaised)
            {
                //HACK
                thisSiege.SiegeEnd(false, DisplayMessages.BattleResults, new string[] { DisplaySiegeResults(battleResults) });
                thisSiege = null;

                // ensure if siege raised correct value returned to Form1.siegeReductionRound method
                if (circumstance.Equals("siege"))
                {
                    attackerVictorious = true;
                }
            }

            // process leader deaths
            if (defenderLeaderDead)
            {
                defenderLeader.ProcessDeath("injury");
            }
            else if (attackerLeaderDead)
            {
                attackerLeader.ProcessDeath("injury");
            }


            // DISBANDMENT

            // if is pillage, attacking (temporary) army always disbands after battle
            if (circumstance.Equals("pillage"))
            {
                attackerDisbanded = true;
            }

            // process army disbandings (after all other functions completed)
            if (attackerDisbanded)
            {
                attacker.DisbandArmy();
                attacker = null;
            }

            if (defenderDisbanded)
            {
                defender.DisbandArmy();
                defender = null;
            }

            return(attackerVictorious);
        }
示例#26
0
        /// <summary>
        /// Generates a new NPC based on parents' statistics
        /// </summary>
        /// <returns>NonPlayerCharacter or null</returns>
        /// <param name="mummy">The new NPC's mother</param>
        /// <param name="daddy">The new NPC's father</param>
        public static NonPlayerCharacter GenerateNewNPC(Character mummy, Character daddy)
        {
            NonPlayerCharacter newNPC = new NonPlayerCharacter();

            // charID
            newNPC.charID = Globals_Game.GetNextCharID();
            // first name
            newNPC.firstName = "Baby";
            // family name
            newNPC.familyName = daddy.familyName;
            // date of birth
            newNPC.birthDate = new Tuple <uint, byte>(Globals_Game.clock.currentYear, Globals_Game.clock.currentSeason);
            // sex
            newNPC.isMale = Birth.GenerateSex();
            // nationality
            newNPC.nationality = daddy.nationality;
            // whether is alive
            newNPC.isAlive = true;
            // maxHealth
            newNPC.maxHealth = Birth.GenerateKeyCharacteristics(mummy.maxHealth, daddy.maxHealth);
            // virility
            newNPC.virility = Birth.GenerateKeyCharacteristics(mummy.virility, daddy.virility);
            // goTo queue
            newNPC.goTo = new Queue <Fief>();
            // language
            newNPC.language = daddy.language;
            // days left
            newNPC.days = 90;
            // stature modifier
            newNPC.statureModifier = 0;
            // management
            newNPC.management = Birth.GenerateKeyCharacteristics(mummy.management, daddy.management);
            // combat
            newNPC.combat = Birth.GenerateKeyCharacteristics(mummy.combat, daddy.combat);
            // traits
            newNPC.traits = Birth.GenerateTraitSetFromParents(mummy.traits, daddy.traits, newNPC.isMale);
            // if in keep
            newNPC.inKeep = mummy.inKeep;
            // if pregnant
            newNPC.isPregnant = false;
            // familyID
            newNPC.familyID = daddy.familyID;
            // spouse
            newNPC.spouse = null;
            // father
            newNPC.father = daddy.charID;
            // mother
            newNPC.mother = mummy.charID;
            // fiancee
            newNPC.fiancee = null;
            // location
            newNPC.location = null;
            // titles
            newNPC.myTitles = new List <string>();
            // armyID
            newNPC.armyID = null;
            // ailments
            newNPC.ailments = new Dictionary <string, Ailment>();
            // employer
            newNPC.employer = null;
            // salary/allowance
            newNPC.salary = 0;
            // lastOffer (will remain empty for family members)
            newNPC.lastOffer = new Dictionary <string, uint>();
            // inEntourage
            newNPC.setEntourage(false);
            // isHeir
            newNPC.isHeir = false;

            return(newNPC);
        }
示例#27
0
        /// <summary>
        /// Processes the actions involved with a marriage
        /// </summary>
        /// <returns>bool indicating whether engagement was processed successfully</returns>
        public bool ProcessMarriage()
        {
            bool success = false;

            // get interested parties
            PlayerCharacter headOfFamilyBride = null;
            PlayerCharacter headOfFamilyGroom = null;
            Character       bride             = null;
            Character       groom             = null;

            for (int i = 0; i < this.personae.Length; i++)
            {
                string   thisPersonae      = this.personae[i];
                string[] thisPersonaeSplit = thisPersonae.Split('|');

                switch (thisPersonaeSplit[1])
                {
                case "headOfFamilyGroom":
                    headOfFamilyGroom = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    break;

                case "headOfFamilyBride":
                    headOfFamilyBride = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    break;

                case "bride":
                    bride = Globals_Game.npcMasterList[thisPersonaeSplit[0]];
                    break;

                case "groom":
                    if (Globals_Game.pcMasterList.ContainsKey(thisPersonaeSplit[0]))
                    {
                        groom = Globals_Game.pcMasterList[thisPersonaeSplit[0]];
                    }
                    else if (Globals_Game.npcMasterList.ContainsKey(thisPersonaeSplit[0]))
                    {
                        groom = Globals_Game.npcMasterList[thisPersonaeSplit[0]];
                    }
                    break;

                default:
                    break;
                }
            }

            // ID
            uint marriageID = Globals_Game.GetNextJournalEntryID();

            // date
            uint year   = Globals_Game.clock.currentYear;
            byte season = Globals_Game.clock.currentSeason;

            // personae
            string headOfFamilyBrideEntry = headOfFamilyBride.charID + "|headOfFamilyBride";
            string headOfFamilyGroomEntry = headOfFamilyGroom.charID + "|headOfFamilyGroom";
            string thisBrideEntry         = bride.charID + "|bride";
            string thisGroomEntry         = groom.charID + "|groom";
            string allEntry = "all|all";

            string[] marriagePersonae = new string[] { headOfFamilyGroomEntry, headOfFamilyBrideEntry, thisBrideEntry, thisGroomEntry, allEntry };

            // type
            string type = "marriage";

            string[] fields = new string[3];
            fields[0] = groom.firstName + " " + groom.familyName;
            fields[1] = bride.firstName + " " + groom.familyName;
            fields[2] = bride.familyName;
            // description

            ProtoMessage marriage = new ProtoMessage();

            marriage.MessageFields = fields;
            marriage.ResponseType  = DisplayMessages.JournalMarriage;
            // create and add a marriage entry to the pastEvents journal
            JournalEntry marriageEntry = new JournalEntry(marriageID, year, season, marriagePersonae, type, marriage, null);

            success = Globals_Game.AddPastEvent(marriageEntry);

            if (success)
            {
                // remove fiancees
                bride.fiancee = null;
                groom.fiancee = null;

                // add spouses
                bride.spouse = groom.charID;
                groom.spouse = bride.charID;

                // change wife's family
                bride.familyID   = groom.familyID;
                bride.familyName = groom.familyName;

                // switch myNPCs
                headOfFamilyBride.myNPCs.Remove(bride as NonPlayerCharacter);
                headOfFamilyGroom.myNPCs.Add(bride as NonPlayerCharacter);

                // move wife to groom's location
                bride.location = groom.location;

                // check to see if headOfFamilyBride should receive increase in stature
                // get highest rank for headOfFamilyBride and headOfFamilyGroom
                Rank brideHighestRank = headOfFamilyBride.GetHighestRank();
                Rank groomHighestRank = headOfFamilyGroom.GetHighestRank();

                // compare ranks
                if ((brideHighestRank != null) && (groomHighestRank != null))
                {
                    if (groomHighestRank.id < brideHighestRank.id)
                    {
                        headOfFamilyBride.AdjustStatureModifier((brideHighestRank.id - groomHighestRank.id) * 0.4);
                    }
                }
            }

            return(success);
        }
示例#28
0
        /// <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);
        }
示例#29
0
        /// <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);
        }
示例#30
0
        /// <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);
        }