protected override string HitsMonsterCombatString(Monster target)
        {
            string combatStr = "";

            if (!Unique)
                combatStr = "The ";

            return combatStr + this.SingleDescription + " " + GetWeaponName() + " at the " + target.SingleDescription + ". It hits.";
        }
        /// <summary>
        /// Increment time - if we have exceeded the duration, call OnExit() and then mark as finished
        /// </summary>
        public override void IncrementTime(Monster target)
        {
            currentTicks++;

            if (currentTicks > GetDuration())
            {
                OnEnd(target);
                hasEnded = true;
            }
        }
Beispiel #3
0
        public CombatResults AttackMonster(Monster monster)
        {
            //The monster always dies
            Game.Dungeon.KillMonster(monster);

            string msg = monster.Representation + " was killed!";
            Game.MessageQueue.AddMessage(msg);
            LogFile.Log.LogEntry(msg);

            return CombatResults.DefenderDied;
        }
        public override CombatResults AttackMonster(Monster monster)
        {
            string msg = this.Representation + " attacked " + monster.Representation;
            LogFile.Log.LogEntryDebug(msg, LogDebugLevel.Medium);

            //Defender always dies
            Game.Dungeon.KillMonster(monster);

            msg = this.Representation + " killed " + monster.Representation + " !";
            LogFile.Log.LogEntryDebug(msg, LogDebugLevel.Medium);
            //Game.MessageQueue.AddMessage(msg);

            return CombatResults.DefenderDied;
        }
Beispiel #5
0
 /// <summary>
 /// Carries out the end effects on the target
 /// </summary>
 public abstract void OnEnd(Monster target);
Beispiel #6
0
        public double CalculateRangedAttackModifiersOnMonster(Monster target)
        {
            var damageModifier = 1.0;

            //Aiming
            damageModifier += CalculateAimBonus();

            //Enemy moving
            /*if (target != null && target.TurnsMoving > 0)
            {
                damageModifier -= 0.2;
            }*/

            return damageModifier;
        }
Beispiel #7
0
        public bool AddMonster(Monster creature, int level, Point location)
        {
            //Try to add a creature at the requested location
            //This may fail due to something else being there or being non-walkable
            try
            {
                Map creatureLevel = levels[level];

                //Check square is accessable
                if (!MapSquareCanBeEntered(level, location))
                {
                    LogFile.Log.LogEntryDebug("AddMonster failure: Square not enterable", LogDebugLevel.Low);
                    return false;
                }

                //Check square has nothing else on it
                SquareContents contents = MapSquareContents(level, location);

                if (contents.monster != null)
                {
                    LogFile.Log.LogEntryDebug("AddMonster failure: Monster at this square", LogDebugLevel.Low);
                    return false;
                }

                if (contents.player != null)
                {
                    LogFile.Log.LogEntryDebug("AddMonster failure: Player at this square", LogDebugLevel.Low);
                    return false;
                }

                //Otherwise OK
                creature.LocationLevel = level;
                creature.LocationMap = location;

                monsters.Add(creature);
                return true;
            }
            catch (Exception ex)
            {
                LogFile.Log.LogEntry(String.Format("AddCreature: ") + ex.Message);
                return false;
            }
        }
Beispiel #8
0
        public CombatResults AttackMonsterRanged(Monster monster, int damage)
        {
            var modifiedDamage = (int)Math.Ceiling(CalculateRangedAttackModifiersOnMonster(monster) * damage);
            string combatResultsMsg = "PvM (ranged) " + monster.Representation + "base " + damage + " modified " + modifiedDamage;
            LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium);

            CancelStealthDueToAttack();
            CancelBoostDueToAttack();

            return ApplyDamageToMonster(monster, modifiedDamage, false, false);
        }
Beispiel #9
0
 public MonsterCommon(Monster mon, int common)
 {
     monster = mon;
     commonness = common;
 }
Beispiel #10
0
        /// <summary>
        /// Add a monster at a random walkable point in the dungeon
        /// Queries the dungeon for walkable places
        /// </summary>
        /// <param name="monster"></param>
        private void AddMonsterRandomWalkablePoint(Monster monster, int level)
        {
            Dungeon dungeon = Game.Dungeon;

            Point location;

            int loops = 0;
            int maxLoops = 50;

            do {
                location = Game.Dungeon.RandomWalkablePointInLevel(level);
                loops++;
            } while (!Game.Dungeon.AddMonster(monster, level, location) && loops < maxLoops);

            if(loops == maxLoops) {
                LogFile.Log.LogEntryDebug("Failed to place: " + monster.Representation, LogDebugLevel.High);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Returns a new monster of this type
        /// </summary>
        /// <param name="monsterType"></param>
        /// <returns></returns>
        private Monster NewMonsterOfType(Monster monsterType)
        {
            if (monsterType is Creatures.Bat)
                 return new Creatures.Bat();

             if (monsterType is Creatures.BlackUnicorn)
                 return new Creatures.BlackUnicorn();

             if (monsterType is Creatures.Bugbear)
                 return new Creatures.Bugbear();

             if (monsterType is Creatures.Demon)
                 return new Creatures.Demon();

             if (monsterType is Creatures.Drainer)
                 return new Creatures.Drainer();

             if (monsterType is Creatures.Faerie)
                 return new Creatures.Faerie();

             if (monsterType is Creatures.Ferret)
                 return new Creatures.Ferret();

             if (monsterType is Creatures.Ghoul)
                 return new Creatures.Ghoul();

             if (monsterType is Creatures.Goblin)
                 return new Creatures.Goblin();

             if (monsterType is Creatures.GoblinWitchdoctor)
                return new Creatures.GoblinWitchdoctor();

             if (monsterType is Creatures.Imp)
                 return new Creatures.Imp();

             if (monsterType is Creatures.Maleficarum)
                 return new Creatures.Maleficarum();

             if (monsterType is Creatures.Meddler)
                 return new Creatures.Meddler();

             if (monsterType is Creatures.Necromancer)
                 return new Creatures.Necromancer();

             if (monsterType is Creatures.Nymph)
                 return new Creatures.Nymph();

             if (monsterType is Creatures.Ogre)
                 return new Creatures.Ogre();

             if (monsterType is Creatures.Orc)
                 return new Creatures.Orc();

             if (monsterType is Creatures.OrcShaman)
                 return new Creatures.OrcShaman();

             if (monsterType is Creatures.Overlord)
                 return new Creatures.Overlord();

             if (monsterType is Creatures.Peon)
                 return new Creatures.Peon();

             if (monsterType is Creatures.Pixie)
                 return new Creatures.Pixie();

             if (monsterType is Creatures.Rat)
                 return new Creatures.Rat();

             if (monsterType is Creatures.SkeletalArcher)
                 return new Creatures.SkeletalArcher();

             if (monsterType is Creatures.Skeleton)
                 return new Creatures.Skeleton();

             if (monsterType is Creatures.Spider)
                 return new Creatures.Spider();

             if (monsterType is Creatures.Uruk)
                 return new Creatures.Uruk();

             if (monsterType is Creatures.Whipper)
                 return new Creatures.Whipper();

             if (monsterType is Creatures.Zombie)
                 return new Creatures.Zombie();

            LogFile.Log.LogEntryDebug("Failed to add a creature of type: " + monsterType.SingleDescription, LogDebugLevel.High);
            return null;
        }
Beispiel #12
0
        private Point PlaceMonsterCloseToLocation(int levelNo, Monster monsterToPlace, Point centerLoc, int looseGroupDist)
        {
            Point location = new Point();

             int innerLoopCount = 0;
             int outerLoopCount = 0;
             do
             {
                 location = Game.Dungeon.RandomWalkablePointInLevel(levelNo);

                 innerLoopCount++;

                 if (Utility.GetDistanceBetween(centerLoc, location) > looseGroupDist && innerLoopCount < 50)
                     continue;

                 outerLoopCount++;

             } while (!Game.Dungeon.AddMonster(monsterToPlace, levelNo, location) && outerLoopCount < 50);

             if(outerLoopCount != 50)
                CheckSpecialMonsterGroups(monsterToPlace, levelNo);

             return location;
        }
Beispiel #13
0
        /// <summary>
        /// Returns true if the monster resisted
        /// </summary>
        /// <param name="monster"></param>
        /// <returns></returns>
        protected bool CheckMagicResistance(Monster monster)
        {
            Player player = Game.Dungeon.Player;

            int monsterRes = monster.GetMagicRes();
            int magicRoll = Game.Random.Next(player.MagicStat);

            LogFile.Log.LogEntryDebug("Magic resistance attempt. Res: " + monsterRes + " Roll: " + magicRoll, LogDebugLevel.Medium);

            if (magicRoll < monsterRes)
            {
                //Charm not successful
                string msg = "The spell energy dissipates around the " + monster.SingleDescription + ".";
                LogFile.Log.LogEntryDebug("Magic resistance - creature resisted", LogDebugLevel.Medium);

                Game.MessageQueue.AddMessage(msg);
                return true;
            }

            return false;
        }
Beispiel #14
0
        public double CalculateMeleeAttackModifiersOnMonster(Monster target)
        {
            var meleeEffect = GetActiveEffects(typeof(PlayerEffects.SpeedBoost));

            var meleeMultiplier = 1.0;

            if (meleeEffect.Count() > 0)
            {
                meleeMultiplier = ((PlayerEffects.SpeedBoost)meleeEffect.First()).Level * 0.5 + 1;
            }

            return meleeMultiplier;
        }
Beispiel #15
0
        public double CalculateDamageModifierForAttacksOnPlayer(Monster target)
        {
            var damageModifier = 1.0;

            var speedEffect = GetActiveEffects(typeof(PlayerEffects.SpeedBoost));

            var speedModifier = 1.0;

            if (speedEffect.Count() > 0)
            {
                speedModifier += ((PlayerEffects.SpeedBoost)speedEffect.First()).Level;
            }

            if(TurnsMoving > 0)
            {
                damageModifier -= 0.2 * speedModifier;
            }

            if (target != null)
            {
                //Test cover
                var coverItems = GetPlayerCover(target);
                var hardCover = coverItems.Item1;
                var softCover = coverItems.Item2;

                if (hardCover > 0)
                    damageModifier -= 0.5;
                if (softCover > 0)
                    damageModifier -= 0.1;
            }

            return Math.Max(0.0, damageModifier);
        }
Beispiel #16
0
        /// <summary>
        /// Attack a monster with modifiers. Takes care of killing them off if required.
        /// </summary>
        /// <param name="monster"></param>
        /// <returns></returns>
        public CombatResults AttackMonsterWithModifiers(Monster monster, int hitModifierMod, int damageBaseMod, int damageModifierMod, int enemyACMod, bool specialMoveUsed)
        {
            //Do we need to recalculate combat stats?
            if (this.RecalculateCombatStatsRequired)
                this.CalculateCombatStats();

            if (monster.RecalculateCombatStatsRequired)
                monster.CalculateCombatStats();

            //Attacking a monster with hand to hand give an instrinsic
            CombatUse = true;

            //Calculate damage from a normal attack

            int damage = AttackWithModifiers(monster, hitModifierMod, damageBaseMod, damageModifierMod, enemyACMod);

            return ApplyDamageToMonster(monster, damage, false, specialMoveUsed);
        }
Beispiel #17
0
        public CombatResults AttackMonsterThrown(Monster monster, int damage)
        {
            string combatResultsMsg = "PvM (thrown) " + monster.Representation + " = " + damage;
            LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium);

            CancelStealthDueToAttack();
            CancelBoostDueToAttack();

            return ApplyDamageToMonster(monster, damage, false, false);
        }
Beispiel #18
0
        /// <summary>
        /// If we have generated a group-bearing monster, add its group
        /// </summary>
        /// <param name="monster"></param>
        /// <param name="levelToPlace"></param>
        private void CheckSpecialMonsterGroups(Monster monster, int levelToPlace)
        {
            int minDistance = 5;

            //Certain monsters spawn in with groups of their friends
            if (monster is Creatures.GoblinWitchdoctor)
            {
                //Spawn in with a random number of ferrets & goblins
                int noFerrets = 2 + Game.Random.Next(4);
                int noGoblins = 1 + Game.Random.Next(3);

                AddMonstersCloseToMaster(new Creatures.Ferret(), noFerrets, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Goblin(), noGoblins, monster, minDistance, levelToPlace);
            }
            else if (monster is Creatures.OrcShaman)
            {
                //Spawn in with a random number of orcs & spiders
                int noOrcs = 2 + Game.Random.Next(3);
                int noSpiders = 1 + Game.Random.Next(2);

                AddMonstersCloseToMaster(new Creatures.Orc(), noOrcs, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Spider(), noSpiders, monster, minDistance, levelToPlace);
            }

            else if (monster is Creatures.Necromancer)
            {
                //Spawn in with a random number of skels & zombs
                int noSkel = 1 + Game.Random.Next(3);
                int noZomb = 1 + Game.Random.Next(2);

                AddMonstersCloseToMaster(new Creatures.Skeleton(), noSkel, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Zombie(), noZomb, monster, minDistance, levelToPlace);
            }

            else if (monster is Creatures.Meddler)
            {
                //Spawn in with a random number of demons & peons
                int noDem = 1 + Game.Random.Next(2);
                int noPeon = 1 + Game.Random.Next(3);

                AddMonstersCloseToMaster(new Creatures.Demon(), noDem, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Peon(), noPeon, monster, minDistance, levelToPlace);
            }

            else if (monster is Creatures.Maleficarum)
            {
                //Spawn in with a random number of demons & whippers
                int noDem = 1 + Game.Random.Next(2);
                int noWhippers = 1 + Game.Random.Next(2);

                AddMonstersCloseToMaster(new Creatures.Demon(), noDem, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Whipper(), noWhippers, monster, minDistance, levelToPlace);
            }
            else if (monster is Creatures.Overlord)
            {
                //Spawn in with a random number of demons, imps and drainers
                int noDem = 1 + Game.Random.Next(3);
                int noImp = 1;
                int noDrainer = 1;

                AddMonstersCloseToMaster(new Creatures.Demon(), noDem, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Imp(), noImp, monster, minDistance, levelToPlace);
                AddMonstersCloseToMaster(new Creatures.Drainer(), noDrainer, monster, minDistance, levelToPlace);
            }
        }
Beispiel #19
0
 /// <summary>
 /// Carries out the start effects on the target.
 /// </summary>
 public abstract void OnStart(Monster target);
Beispiel #20
0
        /// <summary>
        /// Place a monster on level
        /// </summary>
        /// <param name="level"></param>
        /// <param name="monster"></param>
        /// <returns></returns>
        private Point PlaceMonster(int level, Monster monster)
        {
            Point location = new Point();
            int loopCount = 0;
            do
            {
                location = Game.Dungeon.RandomWalkablePointInLevel(level);
                loopCount++;
            } while (!Game.Dungeon.AddMonster(monster, level, location) && loopCount < 1000);

            if (loopCount < 1000)
            {
                CheckSpecialMonsterGroups(monster, level);
            }
            else
            {
                LogFile.Log.LogEntryDebug("Error: Couldn't place monster", LogDebugLevel.High);
            }

            return location;
        }
Beispiel #21
0
 /// <summary>
 /// Carries out the end effects on the target
 /// </summary>
 public abstract void OnEnd(Monster target);
Beispiel #22
0
        /// <summary>
        /// Place the monster, based on type in an appropriate bucket for adding
        /// </summary>
        /// <param name="monster"></param>
        /// <param name="monstersToPlace"></param>
        /// <param name="linearPatrol"></param>
        /// <param name="squarePatrol"></param>
        private void PlaceMonsterInAppropriateClass(Monster monster, List<Monster> monstersToPlace, List<MonsterFightAndRunAI> linearPatrol, List<MonsterFightAndRunAI> squarePatrol)
        {
            if (!(monster is MonsterFightAndRunAI))
            {
                monstersToPlace.Add(monster);
                return;
            }

            MonsterFightAndRunAI monsterAI = monster as MonsterFightAndRunAI;

            if (monsterAI.GetPatrolType() == PatrolType.Waypoints && monsterAI.HasSquarePatrol()) {
                squarePatrol.Add(monsterAI);
                return;
            }

            if (monsterAI.GetPatrolType() == PatrolType.Waypoints)
            {
                linearPatrol.Add(monsterAI);
                return;
            }

            monstersToPlace.Add(monster);
            return;
        }
Beispiel #23
0
 /// <summary>
 /// Called every click. If the event duration is over, call OnEnd() and mark as ended
 /// </summary>
 public abstract void IncrementTime(Monster target);
Beispiel #24
0
        /// <summary>
        /// Add a monster with a random patrol. Needs the mapgenerator of the level in question
        /// </summary>
        /// <param name="monster"></param>
        /// <param name="mapGen"></param>
        private bool AddMonsterFarFromLocation(Monster monster, Point location, int level, MapGenerator mapGen)
        {
            //Offset location

            int maxLoops = 50;
            int loops = 0;

            Point toPlaceLoc = new Point(location);

            int distance = 40;

            do
            {
                toPlaceLoc = new Point(location.x + (int)Gaussian.BoxMuller(distance, 5), location.y + (int)Gaussian.BoxMuller(distance, 5));

                loops++;
                distance--;

            } while (!Game.Dungeon.AddMonster(monster, level, toPlaceLoc) && loops < maxLoops);

            if (loops == maxLoops)
            {
                LogFile.Log.LogEntryDebug("Failed to place: " + monster.Representation + " far from to: " + location + " reverting to random placement", LogDebugLevel.Medium);

                loops = 0;

                do
                {
                    toPlaceLoc = Game.Dungeon.RandomWalkablePointInLevel(level);
                    loops++;

                } while (!Game.Dungeon.AddMonster(monster, level, toPlaceLoc) && loops < maxLoops);

                LogFile.Log.LogEntryDebug("Failed to place: " + monster.Representation + " giving up", LogDebugLevel.High);
                return false;
            }

            LogFile.Log.LogEntryDebug("Item " + monster.Representation + " placed at: " + location.ToString(), LogDebugLevel.High);

            return true;
        }
Beispiel #25
0
        public virtual CombatResults AttackMonster(Monster monster)
        {
            //Recalculate combat stats if required
            if (this.RecalculateCombatStatsRequired)
                this.CalculateCombatStats();

            if (monster.RecalculateCombatStatsRequired)
                monster.CalculateCombatStats();

            //Set the attacked by marker
            monster.LastAttackedBy = this;
            monster.LastAttackedByID = this.UniqueID;

            //Notify the creature that it has been attacked
            monster.NotifyAttackByCreature(this);

            //Wake a sleeping creature
            if (monster.Sleeping)
            {
                monster.WakeCreature();

                //All wake on sight creatures should be awake at this point. If it's a non-wake-on-sight tell the player it wakes
                Game.MessageQueue.AddMessage("The " + monster.SingleDescription + " wakes up!");
                LogFile.Log.LogEntryDebug(monster.Representation + " wakes on attack by monster " + this.Representation, LogDebugLevel.Low);
            }

            //Calculate damage from a normal attack
            int damage = AttackCreatureWithModifiers(monster, 0, 0, 0, 0);

            string messageStr;

            //Do we hit the monster?
            if (damage > 0)
            {
                //Notify the creature that it has been hit
                monster.NotifyHitByCreature(this, damage);

                int monsterOrigHP = monster.Hitpoints;

                monster.Hitpoints -= damage;

                //Is the player dead, if so kill it?
                if (monster.Hitpoints <= 0)
                {
                    Game.Dungeon.KillMonster(monster, false);

                    //Debug string
                    string combatResultsMsg = "MvM " + this.Representation + " vs " + monster.Representation + " ToHit: " + toHitRoll + " AC: " + monster.ArmourClass() + " Dam: 1d" + damageBase + "+" + damageModifier + " MHP: " + monsterOrigHP + "->" + monster.Hitpoints + " killed";
                    messageStr = HitsMonsterCombatString(monster) + " It's knocked out.";
                    Game.MessageQueue.AddMessage(messageStr);
                    //Game.MessageQueue.AddMessage(combatResultsMsg);
                    LogFile.Log.LogEntryDebug(combatResultsMsg, LogDebugLevel.Medium);

                    //Add charm XP if appropriate
                    Game.Dungeon.Player.AddXPMonsterAttack(this, monster);

                    return CombatResults.DefenderDied;
                }

                //Debug string
                string combatResultsMsg3 = "MvM " + this.Representation + " vs " + monster.Representation + " ToHit: " + toHitRoll + " AC: " + monster.ArmourClass() + " Dam: 1d" + damageBase + "+" + damageModifier + " MHP: " + monsterOrigHP + "->" + monster.Hitpoints + " injured";
                messageStr = HitsMonsterCombatString(monster);
                Game.MessageQueue.AddMessage(messageStr);
                LogFile.Log.LogEntryDebug(combatResultsMsg3, LogDebugLevel.Medium);

                return CombatResults.DefenderDamaged;
            }

            //Miss
            string combatResultsMsg2 = "MvM " + this.Representation + " vs " + monster.Representation + " ToHit: " + toHitRoll + " AC: " + monster.ArmourClass() + " Dam: 1d" + damageBase + "+" + damageModifier + " MHP: " + monster.Hitpoints + " miss";
            //Game.MessageQueue.AddMessage(combatResultsMsg2);
            messageStr = MissesMonsterCombatString(monster);
            Game.MessageQueue.AddMessage(messageStr);
            LogFile.Log.LogEntryDebug(combatResultsMsg2, LogDebugLevel.Medium);

            return CombatResults.DefenderUnhurt;
        }
Beispiel #26
0
        /// <summary>
        /// Add cohort monsters close to a unique. Spawns new copies of the cohort monster type passed in (does not use the passed object)
        /// </summary>
        /// <param name="monsterType"></param>
        /// <param name="noMonsters"></param>
        /// <param name="masterMonser"></param>
        /// <param name="minDistance"></param>
        /// <param name="levelNo"></param>
        /// <returns></returns>
        private bool AddMonstersCloseToMaster(Monster monsterType, int noMonsters, Creature masterMonser, int minDistance, int levelNo)
        {
            Point location;

             int outerLoopCount = 0;

             for (int i = 0; i < noMonsters; i++)
             {
                 do
                 {
                     int loopCount = 0;
                     do
                     {
                         location = Game.Dungeon.RandomWalkablePointInLevel(i);
                         loopCount++;
                     } while (Utility.GetDistanceBetween(masterMonser, location) > minDistance && loopCount < maxLoopCount);
                     outerLoopCount++;
                 } while (!Game.Dungeon.AddMonster(NewMonsterOfType(monsterType), levelNo, location) && outerLoopCount < 50);
             }

             //Failed to add monster
             if (outerLoopCount == 50)
             {
                 LogFile.Log.LogEntryDebug("Failed to place a monster near master", LogDebugLevel.Medium);
                 return false;
             }
             return true;
        }
Beispiel #27
0
 protected abstract string HitsMonsterCombatString(Monster target);
Beispiel #28
0
 /// <summary>
 /// Kill a monster. This monster won't get any further turns.
 /// </summary>
 /// <param name="monster"></param>
 public void KillMonster(Monster monster)
 {
     //We can't take the monster out of the collection directly since we might still be iterating through them
     //Instead set a flag on the monster and remove it after all turns are complete
     monster.Alive = false;
 }
Beispiel #29
0
 protected abstract string MissesMonsterCombatString(Monster target);
Beispiel #30
0
 /// <summary>
 /// Called every click. If the event duration is over, call OnEnd() and mark as ended
 /// </summary>
 public abstract void IncrementTime(Monster target);
Beispiel #31
0
 public abstract CombatResults AttackMonster(Monster monster);
Beispiel #32
0
 /// <summary>
 /// Carries out the start effects on the target.
 /// </summary>
 public abstract void OnStart(Monster target);
Beispiel #33
0
 public MonsterEffect(Monster eventReceiver)
     : base(eventReceiver)
 {
     this.monster = eventReceiver;
 }