コード例 #1
0
ファイル: Combat.cs プロジェクト: vadian/Novus
        /// <summary>
        /// Informs all parties of the outcome of the combat round.
        /// </summary>
        /// <param name="player"></param>
        /// <param name="enemy"></param>
        /// <param name="room"></param>
        /// <param name="damage"></param>
        /// <param name="defense"></param>
        /// <param name="attack"></param>
        private static void SendRoundOutcomeMessage(User.User player, User.User enemy, Room room, double damage, double defense, double attack)
        {
            //TODO: Get the message based weapon type/special weapon (blunt, blade, axe, pole, etc.)
            //Get the weapon type and append it to the "Hit" or "Miss" type when getting the message
            //ex: HitSword, HitClub, MissAxe, MissUnarmed could even get really specific HitRustyShortSword, MissLegendaryDaggerOfBlindness
            //Make a method to figure out the type by having a lookup table in the DB that points to a weapon type string
            if (damage < 0)
            {
                player.MessageHandler(ParseMessage(GetMessage("Combat", "Hit", MessageType.Self), player, enemy, damage, defense, attack));
                enemy.MessageHandler(ParseMessage(GetMessage("Combat", "Hit", MessageType.Target), player, enemy, damage, defense, attack));
                string roomMessage = ParseMessage(GetMessage("Combat", "Hit", MessageType.Room), player, enemy, damage, defense, attack);

                room.InformPlayersInRoom(roomMessage, new List <string>(new string[] { player.UserID, enemy.UserID }));
                enemy.Player.ApplyEffectOnAttribute("Hitpoints", damage);

                Character.NPC npc = enemy.Player as Character.NPC;
                if (npc != null)
                {
                    npc.IncreaseXPReward(player.UserID, (damage * -1.0));
                }
            }
            else
            {
                player.MessageHandler(ParseMessage(GetMessage("Combat", "Miss", MessageType.Self), player, enemy, damage, defense, attack));
                enemy.MessageHandler(ParseMessage(GetMessage("Combat", "Miss", MessageType.Target), player, enemy, damage, defense, attack));
                string roomMessage = ParseMessage(GetMessage("Combat", "Miss", MessageType.Room), player, enemy, damage, defense, attack);
                room.InformPlayersInRoom(roomMessage, new List <string>(new string[] { player.UserID, enemy.UserID }));
            }
        }
コード例 #2
0
ファイル: States.cs プロジェクト: vadian/Novus
        public void Execute(Character.NPC actor, ITrigger trigger = null)
        {
            if (actor.StanceState != CharacterEnums.CharacterStanceState.Decomposing)
            {
                Commands.CommandParser.ExecuteCommand(actor, "EMOTE", "carcass last bit of flesh has rotted away from its dead corpse.");
                actor.Description = "The only remains of " + actor.FirstName + " are just bones.";
                actor.SetStanceState(CharacterEnums.CharacterStanceState.Decomposing);
                actor.NextAiAction = DateTime.Now.AddMinutes(5).ToUniversalTime();
            }
            else
            {
                Commands.CommandParser.ExecuteCommand(actor, "EMOTE", "carcass has its bones break down to dust and carried off by the wind.");
                MongoUtils.MongoData.ConnectToDatabase();
                MongoDB.Driver.MongoDatabase   db    = MongoUtils.MongoData.GetDatabase("World");
                MongoDB.Driver.MongoCollection npcs  = db.GetCollection("NPCs");
                MongoDB.Driver.IMongoQuery     query = MongoDB.Driver.Builders.Query.EQ("_id", actor.MobTypeID);

                MongoDB.Bson.BsonDocument doc = npcs.FindOneAs <MongoDB.Bson.BsonDocument>(query);

                doc["Current"] = doc["Current"].AsInt32 - 1;
                npcs.Save(doc);

                db    = MongoUtils.MongoData.GetDatabase("Characters");
                npcs  = db.GetCollection("NPCCharacters");
                query = MongoDB.Driver.Builders.Query.EQ("_id", MongoDB.Bson.ObjectId.Parse(actor.ID));

                npcs.Remove(query);
            }
        }
コード例 #3
0
ファイル: Group.cs プロジェクト: vadian/Novus
        public void Loot(User.User looter, List <string> commands, Character.NPC npc)
        {
            //okay the group looting rule is not free for all thats why we arrived here.  We now need to abide by the looting rule that governs the
            //group.

            //need to create the loot methods for each rule and also add master loot rule
            switch (GroupRuleForLooting)
            {
            case GroupLootRule.Leader_only:
                OnlyLeaderLoots(looter, commands, npc);
                break;

            case GroupLootRule.Next_player_loots:
                NextPlayerLoots(looter, commands, npc);
                break;

            case GroupLootRule.Chance_Loot:
                ChanceLoot(looter, commands, npc);
                break;

            case GroupLootRule.Chance_vote:
                break;

            case GroupLootRule.Master_Looter:
                MasterLooterLoots(looter, commands, npc);
                break;
            }
        }
コード例 #4
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Execute(Character.NPC actor, ITrigger trigger = null)
 {
     Wander.GetState().Execute(actor);                                                                                             //let's go to another room
     actor.NextAiAction = DateTime.Now.AddSeconds(-2).ToUniversalTime();                                                           //set next action back so we will immediately start searching for a target
     FindTarget.GetState().Execute(actor);                                                                                         //let's look for a target
     actor.NextAiAction = DateTime.Now.AddSeconds(Extensions.RandomNumber.GetRandomNumber().NextNumber(10, 31)).ToUniversalTime(); //we are actively looking so the wait time is not long to linger about
 }
コード例 #5
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Enter(Character.NPC actor)
 {
     //ok we were recently in combat and we are in hunt mode otherwise we passed the cool down period and will go back to wandering around
     if (actor.LastCombatTime != DateTime.MinValue.ToUniversalTime() && (DateTime.Now.ToUniversalTime() - actor.LastCombatTime).TotalMinutes >= 10)
     {
         actor.Fsm.ChangeState(Wander.GetState(), actor);
     }
 }
コード例 #6
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Enter(Character.NPC actor)
 {
     //ok when we enter this state we will first set the description to the NPC is sitting here rotting,
     //then decomposing and finally get rid of him on exit
     actor.Description  = "The recently dead carcass of " + actor.FirstName + " is rotting as maggots feast on its entrails.";
     actor.NextAiAction = DateTime.Now.AddMinutes(10).ToUniversalTime();
     actor.Save();
 }
コード例 #7
0
ファイル: AI.cs プロジェクト: vadian/Novus
 public void ChangeState(IState newState, Character.NPC Actor)
 {
     if (state != null && newState != null)
     {
         state.Exit(Actor);
         previousState = state;
         state         = newState;
         state.Enter(Actor);
         Actor.Save();
     }
 }
コード例 #8
0
ファイル: AI.cs プロジェクト: vadian/Novus
 public void Update(Character.NPC Actor)
 {
     if (state != null)
     {
         state.Execute(Actor);
     }
     if (globalState != null)
     {
         globalState.Execute(Actor);
     }
 }
コード例 #9
0
ファイル: States.cs プロジェクト: vadian/Novus
        public void Execute(Character.NPC actor, ITrigger trigger = null)
        {
            //first let's check to see if we got any messages telling us we are being attacked and use that
            //person attacking us as the target
            //if that gets us nowhere, we need to then just kill the first non npc we find in our same location
            Rooms.Room    room = Rooms.Room.GetRoom(actor.Location);
            List <string> playersAtThisLocation = room.GetObjectsInRoom(Rooms.Room.RoomObjects.Players);

            double minutesSinceLastCombat = (DateTime.Now.ToUniversalTime() - actor.LastCombatTime).TotalMinutes;

            //let's start by seeing if we had a last target and the last combat time has been less than 5 minutes ago, if so and he's here, it's payback time
            if (actor.LastTarget != null && minutesSinceLastCombat < 5)
            {
                playersAtThisLocation.AddRange(room.GetObjectsInRoom(Rooms.Room.RoomObjects.Npcs)); //we may have been attacking an npc so let's add them in
                if (playersAtThisLocation.Contains(actor.LastTarget))                               //yeah our previous target is here
                {
                    actor.CurrentTarget = actor.LastTarget;
                }
            }

            //if we don't have a target and we have never been in combat yet, then we are going to find a target OR
            //we've lost interest in our previous target but still have a blooddlust for another 10 minutes
            //so a random person is going to get attacked unless it's been too long since we last attacked someone
            //at this point we should only have actual players in the list to attack (maybe add something so some NPCs can attack other NPCs)
            if ((actor.LastCombatTime == DateTime.MinValue.ToUniversalTime() && actor.CurrentTarget == null) ||
                (actor.CurrentTarget == null && minutesSinceLastCombat >= 5 && minutesSinceLastCombat < 15))
            {
                if (playersAtThisLocation.Count > 0)
                {
                    actor.CurrentTarget = playersAtThisLocation[Extensions.RandomNumber.GetRandomNumber().NextNumber(0, playersAtThisLocation.Count)];
                }
            }

            //we have a target let's attack
            if (actor.CurrentTarget != null)
            {
                if (playersAtThisLocation.Contains(actor.CurrentTarget))
                {
                    Commands.CommandParser.ExecuteCommand(actor, "EMOTE", "growls menancingly at " + MySockets.Server.GetAUser(actor.CurrentTarget).Player.FirstName.CamelCaseWord() + "!");
                    actor.NextAiAction = DateTime.Now.AddSeconds(10).ToUniversalTime(); //give player time to react, maybe even get the first hit
                    actor.Fsm.ChangeState(Combat.GetState(), actor);
                }
            }
            else
            {
                //no targets in sight let's enter hunt mode until things cool down
                actor.Fsm.ChangeState(Hunt.GetState(), actor);
            }
        }
コード例 #10
0
ファイル: Group.cs プロジェクト: vadian/Novus
        //the way this works is the current looter can either loot all or loot a specific item and then his turn is over and the next player gets a chance to loot.
        //the next player can choose to loot something from the current corpse
        private void NextPlayerLoots(User.User looter, List <string> commands, Character.NPC npc)
        {
            if (NextLooterList == null)
            {
                //create th elist of looters in no particular order
                NextLooterList = new Dictionary <int, string>();
                int index = 0;
                foreach (string player in PlayerList)
                {
                    NextLooterList.Add(index, player);
                    index++;
                }
            }

            if (looter.UserID == NextLooterList[CurrentLooter])
            {
                if (npc.Loot(looter, commands, true))
                {
                    //if the player actually loots something then we'll increment the counter
                    CurrentLooter++;
                    if (CurrentLooter > NextLooterList.Count)
                    {
                        CurrentLooter = 0;
                    }
                }
            }
            else
            {
                int playerPosition = 0;
                foreach (var keyValue in NextLooterList)
                {
                    if (keyValue.Value == looter.UserID)
                    {
                        break;
                    }
                    playerPosition++;
                }

                playerPosition -= CurrentLooter;

                if (playerPosition < 0)
                {
                    playerPosition = playerPosition + NextLooterList.Count;
                }

                MySockets.Server.GetAUser(looter.UserID).MessageHandler(string.Format("You are not eligible to loot at this time, it will be your turn in {0} more lootings.", playerPosition));
            }
        }
コード例 #11
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Execute(Character.NPC actor, ITrigger trigger = null)
 {
     if (!actor.IsDead() && !actor.InCombat)
     {
         if (DateTime.Now.ToUniversalTime() > actor.NextAiAction)
         {
             //eventuall this literals will be gotten from the literals table for each different NPC
             Commands.CommandParser.ExecuteCommand(actor, "SAY", "brains...");
             Commands.CommandParser.ExecuteCommand(actor, "EMOTE", "reaches out attempting to grab something");
             actor.NextAiAction = DateTime.Now.AddSeconds(Extensions.RandomNumber.GetRandomNumber().NextNumber(15, 60)).ToUniversalTime();
             if (!FSM.ContinueWithThisState())
             {
                 actor.Fsm.ChangeState(Wander.GetState(), actor);
             }
         }
     }
 }
コード例 #12
0
ファイル: States.cs プロジェクト: vadian/Novus
        public void Execute(Character.NPC actor, ITrigger trigger = null)
        {
            //no target then switch to finding a target first
            if (actor.CurrentTarget == null)
            {
                actor.Fsm.ChangeState(FindTarget.GetState(), actor);
            }
            else  //ok we have someone we can kill, let's do that
                  //if this type of NPC may alert other NPC of the same type in the room to also join in on the fun

            /*
             * if (actor.AlertOthers){
             *  NPCUtils.AlertOtherMobs(actor.Location, actor.MobType, actor.CurrentTarget);
             * }*/
            {
                Commands.CommandParser.ExecuteCommand(actor, "KILL", "target");
            }
        }
コード例 #13
0
ファイル: Combat.cs プロジェクト: vadian/Novus
        /// <summary>
        /// This method sets a player state to unconcious or dead based
        /// </summary>
        /// <param name="player"></param>
        /// <param name="enemy"></param>
        private static void UpdatePlayerState(User.User player, User.User enemy)
        {
            if (enemy.Player.IsUnconcious())
            {
                SendDeadOrUnconciousMessage(player, enemy);
            }
            if (enemy.Player.IsDead())
            {
                SendDeadOrUnconciousMessage(player, enemy, true);

                Character.NPC npc = enemy.Player as Character.NPC;
                if (npc != null)
                {
                    npc.CalculateXP();
                    npc.Fsm.ChangeState(AI.Rot.GetState(), npc);
                    enemy.Player = npc;
                    enemy.Player.Save();
                }
            }
        }
コード例 #14
0
ファイル: Group.cs プロジェクト: vadian/Novus
        //one player will randomly be chosen as the loot winner and can loot something. Once he loots something looting should be opne for all for
        //the corpse that was looted, otherwise another winner is randomly chosen again.
        //this has the drawback that only one corpse is remembered and not all the corpses that got looted not cool.
        private void ChanceLoot(User.User looter, List <string> commands, Character.NPC npc)
        {
            //we don't have a loot winner yet so let's roll the dice
            if (string.IsNullOrEmpty(MasterLooter))
            {
                int    highestRoll = 0;
                string winner      = null;
                foreach (string player in PlayerList)
                {
                    int currentRoll = Extensions.RandomNumber.GetRandomNumber().NextNumber(0, 20);
                    if (currentRoll > highestRoll)
                    {
                        winner = player;
                    }
                }
            }

            //so the looter was the winner or another player in the group is looting a corpse that was previously looted by a previous winner
            if (string.Equals(looter.UserID, MasterLooter) || LastLootedCorpse.Contains(npc.ID))
            {
                if (npc.Loot(looter, commands, true))
                {
                    //if player actually looted something
                    MasterLooter = null;
                    if (!LastLootedCorpse.Contains(npc.ID))
                    {
                        LastLootedCorpse.Add(npc.ID);
                    }
                }
                //we don't need to keep any old ID's since they probably rotted away anyways. Seriously doubt the group looted 100 bodies and then wanted to go
                //back and re-loot one of the 50 first corpses.  This number is subject to change once testing starts happening.
                if (LastLootedCorpse.Count > 100)
                {
                    LastLootedCorpse.RemoveRange(0, 49);
                }
            }
            else
            {
                MySockets.Server.GetAUser(looter.UserID).MessageHandler("You did not win the loot draw and can not loot this corpse.");
            }
        }
コード例 #15
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Execute(Character.NPC actor, ITrigger trigger = null)
 {
     if (actor.StanceState != CharacterEnums.CharacterStanceState.Laying_unconcious &&
         actor.StanceState != CharacterEnums.CharacterStanceState.Laying_dead &&
         actor.StanceState != CharacterEnums.CharacterStanceState.Decomposing)
     {
         if (DateTime.Now.ToUniversalTime() > actor.NextAiAction)  //so it's time for this AI state to execute
         {
             string message = "Hey pal, you looking for trouble?";
             if (trigger.MessageOverrideAsString.Count > 0)
             {
                 message = trigger.MessageOverrideAsString[RandomNumber.GetRandomNumber().NextNumber(0, trigger.MessageOverrideAsString.Count)];
             }
             Commands.CommandParser.ExecuteCommand(actor, "say", message);
         }
     }
     //either way we are not staying in this state, it's just a blip state
     actor.NextAiAction = DateTime.Now.AddSeconds(Extensions.RandomNumber.GetRandomNumber().NextNumber(60, 121)).ToUniversalTime(); //set when we want this action to execute next
     actor.Fsm.RevertState();
     actor.Save();
 }
コード例 #16
0
ファイル: AI.cs プロジェクト: vadian/Novus
        public void InterpretMessage(string message, Character.Iactor actor)
        {
            Character.NPC npc    = actor as Character.NPC;
            MessageParser parser = new MessageParser(message, actor, npc.Triggers);

            parser.FindTrigger();

            //Here's the rub. This call is a sequential call up to this point, maybe we want to
            //kick off a separate thread so that then it won't hold up the players actions and
            //then we can even execute states that operate on a delay.

            if (parser.TriggerToExecute != null)
            {
                IState state = GetStateFromName(parser.TriggerToExecute.StateToExecute);
                if (state != null)
                {
                    ChangeState(state, npc);
                    npc.NextAiAction = DateTime.Now.ToUniversalTime().AddSeconds(-1); //this state will execute next now
                    state.Execute(npc, parser.TriggerToExecute);
                }
            }
        }
コード例 #17
0
ファイル: States.cs プロジェクト: vadian/Novus
        public void Execute(Character.NPC actor, ITrigger trigger = null)
        {
            if (!actor.IsDead() && !actor.InCombat)
            {
                Rooms.Room room = Rooms.Room.GetRoom(actor.Location);
                room.GetRoomExits();
                List <Rooms.Exits> availableExits = room.RoomExits;
                if (DateTime.Now.ToUniversalTime() > actor.NextAiAction)  //so it's time for this AI state to execute
                {
                    Commands.CommandParser.ExecuteCommand(actor, availableExits[Extensions.RandomNumber.GetRandomNumber().NextNumber(0, availableExits.Count)].Direction);
                    actor.NextAiAction = DateTime.Now.AddSeconds(Extensions.RandomNumber.GetRandomNumber().NextNumber(60, 121)).ToUniversalTime(); //set when we want this action to execute next
                    if (!FSM.ContinueWithThisState())
                    {
                        actor.Fsm.ChangeState(Speak.GetState(), actor);
                    }
                }
            }

            if (actor.InCombat)
            {
                actor.Fsm.ChangeState(Combat.GetState(), actor);
            }
        }
コード例 #18
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Exit(Character.NPC actor)
 {
 }
コード例 #19
0
ファイル: Combat.cs プロジェクト: vadian/Novus
        //finisher moves
        //these will actually be skill moves
        private static void Cleave(User.User player, List <string> commands)         //this will need a check in the future to be used with only bladed weapons
        {
            User.User enemy = null;
            if (commands.Count > 2)
            {
                foreach (User.User foe in MySockets.Server.GetAUserByFirstName(commands[2]))
                {
                    if (foe.Player.Location == player.Player.Location)
                    {
                        enemy = foe;
                    }
                }
            }
            else  //did not specify a name let's kill the first player we find unconcious in our same location
            {
                enemy = MySockets.Server.GetCurrentUserList().Where(u => u.Player.Location == player.Player.Location && String.Compare(u.Player.ActionState.ToString(), "unconcious", true) == 0).SingleOrDefault();
            }

            if (enemy == null)
            {
                //ok it's not a player lets look through the NPC list
                foreach (Character.NPC npc in Character.NPCUtils.GetAnNPCByName(commands[2], player.Player.Location))
                {
                    if (npc.ActionState == CharacterEnums.CharacterActionState.Unconcious)
                    {
                        User.User foe = new User.User(true);
                        foe.UserID = npc.ID;
                        foe.Player = npc;
                        enemy      = foe;
                        break;
                    }
                }
            }

            if (enemy == null)
            {
                player.MessageHandler("You can't kill what you can't see!");
                return;
            }
            Room room = Room.GetRoom(player.Player.Location);

            if (String.Compare(enemy.Player.ActionState.ToString(), "unconcious", true) == 0)
            {
                if (commands.Count > 3 && commands[3].ToLower() == "slowly")                    //a slow death for your opponent, bask in it.
                {
                    player.MessageHandler(String.Format("You slowly drive your blade through {0}'s chest and twist it a few times as {1} lays on the ground unconcious.", enemy.Player.FirstName, enemy.Player.Gender == "Male" ? "he" : "she"));
                    enemy.MessageHandler(String.Format("{0} slowly drives {1} blade through your chest and twists it a few times as you lay on the ground unconcious.", player.Player.FirstName, player.Player.Gender == "Male" ? "his" : "her"));
                    string roomMessage = String.Format("{0} slowly drives {1} blade through {2}'s chest and twists it a few times as {3} lay on the ground unconcious.", player.Player.FirstName, player.Player.Gender == "Male" ? "his" : "her", enemy.Player.FirstName, enemy.Player.Gender == "Male" ? "he" : "she");
                    room.InformPlayersInRoom(roomMessage, new List <string>(new string[] { player.UserID, enemy.UserID }));
                    ;
                }
                else
                {
                    player.MessageHandler(String.Format("You cleave {0} as {1} lays on the ground unconcious.", enemy.Player.FirstName, enemy.Player.Gender == "Male" ? "he" : "she"));
                    enemy.MessageHandler(String.Format("{0} cleaved you as you lay on the ground unconcious.", player.Player.FirstName));
                    string roomMessage = String.Format("{0} cleaved {1} as {2} lay on the ground unconcious.", player.Player.FirstName, enemy.Player.FirstName, enemy.Player.Gender == "Male" ? "he" : "she");
                    room.InformPlayersInRoom(roomMessage, new List <string>(new string[] { player.UserID, enemy.UserID }));
                }
                enemy.Player.SetAttributeValue("Hitpoints", -100);
                //SetDead(player, enemy);
                Character.NPC npc = enemy.Player as Character.NPC;
                if (npc != null)
                {
                    if (npc.IsDead())
                    {
                        npc.Fsm.ChangeState(AI.Rot.GetState(), npc);
                    }
                }
            }
            else
            {
                player.MessageHandler(String.Format("You can't cleave {0}, {1} not unconcious.", enemy.Player.FirstName, enemy.Player.Gender == "Male" ? "he's" : "she's"));
            }
        }
コード例 #20
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Enter(Character.NPC actor)
 {
     Commands.CommandParser.ExecuteCommand(actor, "EMOTE", "starts looking around for something to attack");
     actor.NextAiAction = DateTime.Now.AddSeconds(30).ToUniversalTime(); //this way players will have some time to react and/or run away
 }
コード例 #21
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Enter(Character.NPC actor)
 {
     actor.NextAiAction = DateTime.Now.AddSeconds(Extensions.RandomNumber.GetRandomNumber().NextNumber(60, 121)).ToUniversalTime();
 }
コード例 #22
0
ファイル: States.cs プロジェクト: vadian/Novus
 public void Enter(Character.NPC actor)
 {
     //no target, no fighting
 }