public Monster GetMonster(MonsterClass monsterClass, MonsterBehavior monsterBehavior)
        {
            var key = GetKey(monsterClass, monsterBehavior);

            if (_flyweights.Any(x => x.Item2 == key))
            {
                return(_flyweights.FirstOrDefault(t => t.Item2 == key)?.Item1);
            }

            Monster monster;

            switch (monsterBehavior)
            {
            case MonsterBehavior.Fire:
                monster = new Monster(new FireBehavior(), monsterClass);
                break;

            default:
                monster = new Monster(new WaterBehavior(), monsterClass);
                break;
            }

            _flyweights.Add(new Tuple <Monster, int>(monster, key));

            return(_flyweights.FirstOrDefault(t => t.Item2 == key)?.Item1);
        }
Beispiel #2
0
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        MonsterBehavior behavior = animator.gameObject.GetComponent <MonsterBehavior>();

        behavior.teleport(behavior.spawn);
        Debug.Log("teleport");
    }
Beispiel #3
0
 protected void OnTriggerEnter(Collider other)
 {
     if (other.gameObject.CompareTag("Enemy"))
     {
         int dmg = playerStat.GetDamage();
         blood.LifeSteal(dmg);
         blood.ResetTimer();
         MonsterBehavior monsterBehavior = other.GetComponent <MonsterBehavior>();
         monsterBehavior.Knockback((monsterBehavior.transform.position - GameObject.FindGameObjectWithTag("Player").transform.position) * 5);
         SpriteRenderer[] spriteRenderers = other.GetComponentsInChildren <SpriteRenderer>();
         foreach (SpriteRenderer spr in spriteRenderers)
         {
             Sequence seq = DOTween.Sequence();
             seq.Append(spr.DOColor(Color.red, 0.1f));
             seq.Append(spr.DOColor(Color.white, 0.1f));
             seq.Play();
         }
         if (other.GetComponent <MonsterBehavior>().ReceiveDamage(dmg))
         {
             GameObject[] manager = GameObject.FindGameObjectsWithTag("Manager");
             if (manager.Length != 0)
             {
                 manager[0].GetComponent <GameEvent>().SetKillEnnemy();
             }
             blood.OnKill();
         }
     }
 }
Beispiel #4
0
    protected override void monsterMovement()
    {
        if (!targetPlayer)
        {
            // If rabbit is 70 distance from entrance, make it go there.
            // Otherwise, let it wander a bit.
            Vector3 closestCastlePos = new Vector3(transform.position.x,
                                                   transform.position.y,
                                                   target.transform.position.z);
            if (Vector3.Distance(transform.position, closestCastlePos) < targetPlayerDist)
            {
                MonsterBehavior.FollowStandingTargetStart(agent, target.transform.position);
                targetPlayer = true;
            }
            else if (!staggered)
            {
                Wander();
            }
        }

        // Update animator parameter to denote movement
        if (Vector3.Distance(agent.velocity, Vector3.zero) != 0.0)
        {
            anim.SetBool("Moving", true);
        }
        else
        {
            anim.SetBool("Moving", false);
        }
    }
Beispiel #5
0
 private void attack(int a, MonsterBehavior ai)
 {
     if (AttackRange >= Vector2.Distance(transform.position, target.transform.position))
     {
         Vector2 dir = getTargetDir(ai);
         interact.Attack(a, dir);
     }
 }
Beispiel #6
0
 override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
 {
     behavior = animator.gameObject.GetComponent <MonsterBehavior>();
     Debug.Log(behavior.spawn);
     behavior.setMovement("waypoint");
     Debug.Log("picking");
     behavior.nextPoint();
 }
 private void Start()
 {
     #region Component Initialization
     AiData    = GetComponent <AIData>();
     Behaviour = AiData.GetComponent <MonsterBehavior>();
     Checks    = AiData.GetComponent <MonsterChecks>();
     #endregion
 }
Beispiel #8
0
 private void attack(int a, MonsterBehavior ai)
 {
     if (coolDowns[a] <= 0 && interact.attacks[a].AttackRange >= Vector2.Distance(transform.position, target.transform.position))
     {
         Vector2 dir = getTargetDir(ai);
         interact.Attack(a, dir);
         coolDowns[a] = baseCoolDowns[a];
     }
 }
Beispiel #9
0
 private void move(MonsterBehavior ai)
 {
     if (InterVallCountdown <= 0)
     {
         Vector2 dir = getTargetDir(ai);
         rigidbody2D.velocity = dir * Speed;
         InterVallCountdown   = movementIntervall;
     }
 }
Beispiel #10
0
        public World(CommonResource resorces, GameOptions options, DoomGame game)
        {
            this.WorldEntity = EntityInfo.Create(this, EntityInfo.OfType <DoomEngine.Game.Entities.World>());

            this.options = options;
            this.game    = game;
            this.random  = game != null ? game.Random : new DoomRandom();

            this.map              = new Map(resorces, this);
            this.thinkers         = new Thinkers(this);
            this.specials         = new Specials(this);
            this.thingAllocation  = new ThingAllocation(this);
            this.thingMovement    = new ThingMovement(this);
            this.thingInteraction = new ThingInteraction(this);
            this.mapCollision     = new MapCollision(this);
            this.mapInteraction   = new MapInteraction(this);
            this.pathTraversal    = new PathTraversal(this);
            this.hitscan          = new Hitscan(this);
            this.visibilityCheck  = new VisibilityCheck(this);
            this.sectorAction     = new SectorAction(this);
            this.playerBehavior   = new PlayerBehavior(this);
            this.itemPickup       = new ItemPickup(this);
            this.weaponBehavior   = new WeaponBehavior(this);
            this.monsterBehavior  = new MonsterBehavior(this);
            this.lightingChange   = new LightingChange(this);
            this.autoMap          = new AutoMap(this);
            this.cheat            = new Cheat(this);

            options.IntermissionInfo.ParTime = 180;

            options.Player.KillCount   = 0;
            options.Player.SecretCount = 0;
            options.Player.ItemCount   = 0;

            // Initial height of view will be set by player think.
            options.Player.ViewZ = Fixed.Epsilon;

            this.totalKills   = 0;
            this.totalItems   = 0;
            this.totalSecrets = 0;

            this.LoadThings();

            this.statusBar = new StatusBar(this);

            this.specials.SpawnSpecials();

            this.levelTime    = 0;
            this.doneFirstTic = false;
            this.secretExit   = false;
            this.completed    = false;

            this.validCount = 0;

            options.Music.StartMusic(Map.GetMapBgm(options), true);
        }
 private static int GetKey(MonsterClass monsterClass, MonsterBehavior monsterBehavior)
 {
     unchecked
     {
         var hash = 13;
         hash = (hash * 7) + monsterClass.GetHashCode();
         hash = (hash * 7) + (monsterBehavior.GetHashCode());
         return(hash);
     }
 }
Beispiel #12
0
 // Update is called once per frame
 void Update()
 {
     if (!Enemy)
     {
         Enemy = FindObjectOfType <MonsterBehavior>();
     }
     if (!Enemy)
     {
         return;
     }
     EnemyHealthSlider.value = Enemy.stats.GetStat("EnemyHealth").Value;
     EnemyHitPoints.text     = Enemy.stats.GetStat("EnemyHealth").Value.ToString();
 }
Beispiel #13
0
    protected IEnumerator ExecuteCurry(float time, int shots, int pellets)
    {
        //things to happen before delay
        GameObject      newAttack;
        MonsterBehavior behave = this.GetComponent <MonsterBehavior>();

        // null check on curryball projectile
        if (behave.projectile == null)
        {
            yield return(null);
        }

        // spawn the amount of shots with the amount of pellets
        var s = shots;

        // toggle between red and more red
        SpriteRenderer sr        = this.GetComponent <SpriteRenderer>();
        float          colorLerp = 0.25f;

        sr.color = Color.Lerp(Color.yellow, Color.red, colorLerp);
        while (s > 0)
        {
            colorLerp += Time.deltaTime * 15;
            sr.color   = Color.Lerp(Color.yellow, Color.red, colorLerp);

            yield return(new WaitForSeconds(time));

            colorLerp = 0.5f;
            // spawn curry balls
            var split = 360 / pellets;
            for (int i = 0; i < pellets; i++)
            {
                // spawn curry ball at an angle
                newAttack = Instantiate(behave.projectile, transform.position, Quaternion.identity);
                Vector2 dir = Vector2.ClampMagnitude(pv.Ang2Vec((split * i) + (s * 30)), 1f);/*+ Random.Range(-split/4, split/4)*/

                BaseProjectile projectileData = newAttack.GetComponent <BaseProjectile>();

                projectileData.directionVector  = dir;
                projectileData.penetrateTargets = true;
                projectileData.attacker         = this.gameObject;
            }
            s--;
        }
        //things to happen after delay
        Debug.Log("no longer CURRIED");
        spriteRenderer.color = Color.white;
        yield return(null);
    }
Beispiel #14
0
    public MonsterBehavior CreateMonster(uint sceneid, string uid, int entityType, GameObject go)
    {
        MonsterBehavior monster = go.GetComponent <MonsterBehavior>();

        if (monster == null)
        {
            monster = go.AddComponent <MonsterBehavior>();
        }
        entityBehaviors.Add(uid, monster);
        monster.uid        = uid;
        monster.entityType = entityType;
        monster.sceneid    = sceneid;

        monster.OnNewObject();
        return(monster);
    }
Beispiel #15
0
    private Vector2 getTargetDir(MonsterBehavior ai)
    {
        Vector2 returnDir = Vector2.zero;

        if (ai == MonsterBehavior.Simple)
        {
            returnDir = (target.transform.position - transform.position).normalized;
        }

        else if (ai == MonsterBehavior.Classic)
        {
            int degree = Random.Range(0, numberOfDirs);
            degree *= (360 / numberOfDirs);
            float radian = degree * Mathf.Deg2Rad;
            returnDir = new Vector2(Mathf.Cos(radian), Mathf.Sin(radian));
        }
        return(returnDir);
    }
    private void Start()
    {
        #region Initialize Components
        Behavior = GetComponent <MonsterBehavior>();
        Protocol = GetComponent <MonsterProtocols>();
        Checks   = GetComponent <MonsterChecks>();
        Curves   = GetComponent <UtilityCurves>();
        #endregion
        #region Initialize Data
        InitializeCharacterData();
        InitializeNormalValues();
        #endregion
        path = new List <TileNode>();

        _vectors = new Dictionary <string, Vector2> {
            { "Player", new Vector2(0f, 0f) }
        };
    }
 static int CreateMonster(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 5);
         EntityBehaviorMgr obj       = (EntityBehaviorMgr)ToLua.CheckObject(L, 1, typeof(EntityBehaviorMgr));
         uint   arg0                 = (uint)LuaDLL.luaL_checknumber(L, 2);
         string arg1                 = ToLua.CheckString(L, 3);
         int    arg2                 = (int)LuaDLL.luaL_checknumber(L, 4);
         UnityEngine.GameObject arg3 = (UnityEngine.GameObject)ToLua.CheckUnityObject(L, 5, typeof(UnityEngine.GameObject));
         MonsterBehavior        o    = obj.CreateMonster(arg0, arg1, arg2, arg3);
         ToLua.Push(L, o);
         return(1);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
Beispiel #18
0
        private IEnumerable <MonsterBehavior> GetMonsterBehaviorsFromLines(IReadOnlyList <string> behaviorLines, MonsterBehaviorType behaviorType)
        {
            var monsterBehaviors = new List <MonsterBehavior>();

            List <int> behaviorLinesIndexes;

            if (behaviorType == MonsterBehaviorType.Legendary)
            {
                behaviorLinesIndexes = Enumerable.Range(0, behaviorLines.Count)
                                       .Where(i => behaviorLines[i].StartsWith("> **") || behaviorLines[i].StartsWith(">**"))
                                       .ToList();
            }
            else
            {
                behaviorLinesIndexes = Enumerable.Range(0, behaviorLines.Count)
                                       .Where(i => behaviorLines[i].StartsWith("> ***") || behaviorLines[i].StartsWith(">***"))
                                       .ToList();
            }

            for (var i = 0; i < behaviorLinesIndexes.Count; i++)
            {
                List <string> singleBehaviorLines;
                if (i + 1 < behaviorLinesIndexes.Count)
                {
                    singleBehaviorLines = behaviorLines.Skip(behaviorLinesIndexes[i])
                                          .Take(behaviorLinesIndexes[i + 1] - behaviorLinesIndexes[i]).ToList();
                }
                else
                {
                    singleBehaviorLines = behaviorLines.Skip(behaviorLinesIndexes[i]).ToList();
                }

                if (behaviorType == MonsterBehaviorType.Legendary)
                {
                    var baseLine      = singleBehaviorLines.First(b => b.StartsWith("> **") || b.StartsWith(">**"));
                    var baseLineSplit = baseLine.Split(new[] { "**", "**" }, StringSplitOptions.None);
                    var parenIndex    = baseLineSplit[1].IndexOf('(');

                    var    name         = baseLineSplit[1].Trim().Replace(".", string.Empty);
                    string restrictions = null;
                    if (parenIndex != -1)
                    {
                        name = baseLineSplit[1].Remove(parenIndex).Trim();

                        var restrictionsSplit = baseLine.Split('(', ')');
                        if (restrictionsSplit.ElementAtOrDefault(1) != null)
                        {
                            restrictions = restrictionsSplit[1].Trim();
                        }
                    }

                    var descriptionFinal = string
                                           .Join(" ", new List <string>(singleBehaviorLines.Skip(1))
                    {
                        baseLine.Split("**")[2].Trim()
                    })
                                           .RemoveMarkdownCharacters();

                    var monsterBehavior = new MonsterBehavior
                    {
                        MonsterBehaviorTypeEnum = behaviorType,
                        Name                 = name.RemoveMarkdownCharacters(),
                        Description          = descriptionFinal,
                        DescriptionWithLinks = descriptionFinal,
                        Restrictions         = restrictions
                    };

                    monsterBehaviors.Add(monsterBehavior);
                }
                else
                {
                    var baseLine    = singleBehaviorLines.First(b => b.StartsWith("> **") || b.StartsWith(">**"));
                    var description = singleBehaviorLines.Skip(1).ToList();
                    description.Insert(0, baseLine.Split("***")[2].Trim());

                    var baseLineSplit = baseLine.Split(new[] { "***", "***" }, StringSplitOptions.None);
                    var parenIndex    = baseLineSplit[1].IndexOf('(');

                    var    name         = baseLineSplit[1].Trim().Replace(".", string.Empty);
                    string restrictions = null;
                    if (parenIndex != -1)
                    {
                        name = baseLineSplit[1].Remove(parenIndex).Trim();

                        var restrictionsSplit = baseLine.Split('(', ')');
                        if (restrictionsSplit.ElementAtOrDefault(1) != null)
                        {
                            restrictions = restrictionsSplit[1].Trim();
                        }
                    }

                    var descriptionFinal = string
                                           .Join(" ", new List <string>(singleBehaviorLines.Skip(1))
                    {
                        baseLine.Split("**")[2].Trim()
                    })
                                           .RemoveMarkdownCharacters();

                    var descriptionWithLinks = descriptionFinal;

                    var castingLevels = new List <string>
                    {
                        Localization.AtWill, Localization.FirstLevel, Localization.SecondLevel, Localization.ThirdLevel,
                        Localization.FourthLevel, Localization.FifthLevel, Localization.SixthLevel,
                        Localization.SeventhLevel, Localization.EighthLevel, Localization.NinthLevel
                    };
                    castingLevels.AddRange(castingLevels.Select(c => c.Replace(' ', '-')).ToList());

                    if (name.Contains("casting", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var lines = new List <string>(singleBehaviorLines);

                        for (var j = 0; j < lines.Count; j++)
                        {
                            var c = castingLevels.FirstOrDefault(c => Regex.IsMatch(lines[j], @"^>\s*.*:", RegexOptions.IgnoreCase));
                            if (c != null)
                            {
                                var powerLineSplit = lines[j].Split(':');
                                var powers         = powerLineSplit[1].RemoveMarkdownCharacters().Split(',')
                                                     .Select(s => s.Trim());
                                var powersUpdated = new List <string>();
                                foreach (var power in powers)
                                {
                                    powersUpdated.Add($"[{power}](#{Uri.EscapeUriString(power)})");
                                }

                                lines[j] = $"{powerLineSplit[0]}: *{string.Join(", ", powersUpdated)}*";
                            }
                        }

                        descriptionWithLinks = string
                                               .Join("\r\n", lines)
                                               .RemoveMarkdownCharacters();
                    }

                    var monsterBehavior = new MonsterBehavior
                    {
                        MonsterBehaviorTypeEnum = behaviorType,
                        Name                 = name.RemoveMarkdownCharacters(),
                        Description          = descriptionFinal,
                        DescriptionWithLinks = descriptionWithLinks,
                        Restrictions         = restrictions
                    };

                    if (Regex.IsMatch(baseLine.Split("***")[2].Trim(), @"\*.+\*"))
                    {
                        if (behaviorType == MonsterBehaviorType.Action)
                        {
                            if (baseLine.Split("***")[2].Trim().Contains($"*{Localization.melee}", StringComparison.InvariantCultureIgnoreCase))
                            {
                                monsterBehavior.AttackTypeEnum = AttackType.MeleeWeapon;
                            }
                            else if (baseLine.Split("***")[2].Trim().Contains($"*{Localization.ranged}",
                                                                              StringComparison.InvariantCultureIgnoreCase))
                            {
                                monsterBehavior.AttackTypeEnum = AttackType.RangedWeapon;
                            }
                            else
                            {
                                monsterBehavior.AttackTypeEnum = AttackType.None;
                            }

                            var attackSplit      = baseLine.Split("***")[2].Trim().Split(',').Select(s => s.Trim()).ToList();
                            var hitSplit         = Regex.Split(baseLine.Split("***")[2].Trim(), Localization.MonsterHitSplitPattern);
                            var hitCommaSplit    = hitSplit.SafeAccess(0)?.Split(',')?.ToList() ?? new List <string>();
                            var hitSpaceSplit    = hitSplit.SafeAccess(1)?.Split(' ')?.ToList() ?? new List <string>();
                            var didParseAttBonus = int.TryParse(Regex.Match(attackSplit[0], @"-?\d+").Value, out var parsedAttBonus);
                            monsterBehavior.AttackBonus     = didParseAttBonus ? parsedAttBonus : 0;
                            monsterBehavior.Range           = attackSplit.ToArray().SafeAccess(1)?.Trim() ?? "";
                            monsterBehavior.NumberOfTargets = hitCommaSplit.ToArray().SafeAccess(2)?.Trim();

                            if (Regex.IsMatch(hitSplit.SafeAccess(1)?.Trim() ?? string.Empty, @"^\d+.*\(.*\)"))
                            {
                                monsterBehavior.Damage     = Regex.Match(hitSplit.SafeAccess(1) ?? string.Empty, @"-?\d+").Value.Trim();
                                monsterBehavior.DamageRoll = hitSplit.SafeAccess(1)?.Split('(', ')').ElementAtOrDefault(1)?.Trim();
                                if (hitSpaceSplit.FindIndex(f =>
                                                            f.Contains(Localization.damage, StringComparison.InvariantCultureIgnoreCase)) != -1)
                                {
                                    if (Enum.TryParse(hitSpaceSplit[hitSpaceSplit.FindIndex(f => f.Contains(Localization.damage, StringComparison.InvariantCultureIgnoreCase)) - 1],
                                                      true, out DamageType damageType) &&
                                        Enum.IsDefined(typeof(DamageType), damageType))
                                    {
                                        monsterBehavior.DamageTypeEnum = damageType;
                                    }
                                    else
                                    {
                                        monsterBehavior.DamageTypeEnum = DamageType.Unknown;
                                    }
                                }
                            }
                        }
                    }

                    monsterBehaviors.Add(monsterBehavior);
                }
            }

            return(monsterBehaviors);
        }
 protected AttackCommand(MonsterBehavior monsterBehavior)
 {
     MonsterBehavior = monsterBehavior;
 }
Beispiel #20
0
        public World(CommonResource resorces, GameOptions options, DoomGame game)
        {
            this.options = options;
            this.game    = game;

            if (game != null)
            {
                this.random = game.Random;
            }
            else
            {
                this.random = new DoomRandom();
            }

            this.map = new Map(resorces, this);

            this.thinkers         = new Thinkers(this);
            this.specials         = new Specials(this);
            this.thingAllocation  = new ThingAllocation(this);
            this.thingMovement    = new ThingMovement(this);
            this.thingInteraction = new ThingInteraction(this);
            this.mapCollision     = new MapCollision(this);
            this.mapInteraction   = new MapInteraction(this);
            this.pathTraversal    = new PathTraversal(this);
            this.hitscan          = new Hitscan(this);
            this.visibilityCheck  = new VisibilityCheck(this);
            this.sectorAction     = new SectorAction(this);
            this.playerBehavior   = new PlayerBehavior(this);
            this.itemPickup       = new ItemPickup(this);
            this.weaponBehavior   = new WeaponBehavior(this);
            this.monsterBehavior  = new MonsterBehavior(this);
            this.lightingChange   = new LightingChange(this);
            this.autoMap          = new AutoMap(this);
            this.cheat            = new Cheat(this);

            options.IntermissionInfo.TotalFrags = 0;
            options.IntermissionInfo.ParTime    = 180;

            for (var i = 0; i < Player.MaxPlayerCount; i++)
            {
                options.Players[i].KillCount   = 0;
                options.Players[i].SecretCount = 0;
                options.Players[i].ItemCount   = 0;
            }

            // Initial height of view will be set by player think.
            options.Players[options.ConsolePlayer].ViewZ = Fixed.Epsilon;

            this.totalKills   = 0;
            this.totalItems   = 0;
            this.totalSecrets = 0;

            this.LoadThings();

            this.statusBar = new StatusBar(this);

            // If deathmatch, randomly spawn the active players.
            if (options.Deathmatch != 0)
            {
                for (var i = 0; i < Player.MaxPlayerCount; i++)
                {
                    if (options.Players[i].InGame)
                    {
                        options.Players[i].Mobj = null;
                        this.thingAllocation.DeathMatchSpawnPlayer(i);
                    }
                }
            }

            this.specials.SpawnSpecials();

            this.levelTime    = 0;
            this.doneFirstTic = false;
            this.secretExit   = false;
            this.completed    = false;

            this.validCount = 0;

            this.displayPlayer = options.ConsolePlayer;

            options.Music.StartMusic(Map.GetMapBgm(options), true);
        }
Beispiel #21
0
    protected override void monsterInit()
    {
        Vector3 dest = new Vector3(transform.position.x, transform.position.y, target.transform.position.z);

        MonsterBehavior.FollowStandingTargetStart(agent, dest);
    }
Beispiel #22
0
    protected void Wander()
    {
        float destChangeRate = UnityEngine.Random.Range(minDestChangeRate, maxDestChangeRate);

        MonsterBehavior.Wander(agent, gameObject, mask, wanderRadius, destChangeRate, ref nextDestChange);
    }
Beispiel #23
0
    override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
    {
        MonsterBehavior behavior = animator.gameObject.GetComponent <MonsterBehavior>();

        behavior.setMovement("player");
    }
Beispiel #24
0
 private void Start()
 {
     _behave = GetComponent <MonsterBehavior>();
 }
 private void Start()
 {
     monsterBehavior = GetComponentInParent <MonsterBehavior>();
 }
Beispiel #26
0
 protected override void monsterInit()
 {
     MonsterBehavior.FollowStandingTargetStart(agent, target.transform.position);
 }
Beispiel #27
0
        private IEnumerable <MonsterBehavior> GetMonsterBehaviorsFromLines(IReadOnlyList <string> behaviorLines, MonsterBehaviorType behaviorType)
        {
            var monsterBehaviors = new List <MonsterBehavior>();

            List <int> behaviorLinesIndexes;

            if (behaviorType == MonsterBehaviorType.Legendary)
            {
                behaviorLinesIndexes = Enumerable.Range(0, behaviorLines.Count)
                                       .Where(i => behaviorLines[i].StartsWith("> **") || behaviorLines[i].StartsWith(">**"))
                                       .ToList();
            }
            else
            {
                behaviorLinesIndexes = Enumerable.Range(0, behaviorLines.Count)
                                       .Where(i => behaviorLines[i].StartsWith("> ***") || behaviorLines[i].StartsWith(">***"))
                                       .ToList();
            }

            for (var i = 0; i < behaviorLinesIndexes.Count; i++)
            {
                List <string> singleBehaviorLines;
                if (i + 1 < behaviorLinesIndexes.Count)
                {
                    singleBehaviorLines = behaviorLines.Skip(behaviorLinesIndexes[i])
                                          .Take(behaviorLinesIndexes[i + 1] - behaviorLinesIndexes[i]).ToList();
                }
                else
                {
                    singleBehaviorLines = behaviorLines.Skip(behaviorLinesIndexes[i]).ToList();
                }

                if (behaviorType == MonsterBehaviorType.Legendary)
                {
                    var baseLine      = singleBehaviorLines.First(b => b.StartsWith("> **") || b.StartsWith(">**"));
                    var baseLineSplit = baseLine.Split(new[] { "**", "**" }, StringSplitOptions.None);
                    var parenIndex    = baseLineSplit[1].IndexOf('(');

                    var    name         = baseLineSplit[1].Trim().Replace(".", string.Empty);
                    string restrictions = null;
                    if (parenIndex != -1)
                    {
                        name = baseLineSplit[1].Remove(parenIndex).Trim();

                        var restrictionsSplit = baseLine.Split('(', ')');
                        if (restrictionsSplit.ElementAtOrDefault(1) != null)
                        {
                            restrictions = restrictionsSplit[1].Trim();
                        }
                    }

                    var monsterBehavior = new MonsterBehavior
                    {
                        MonsterBehaviorTypeEnum = behaviorType,
                        Name        = name.RemoveMarkdownCharacters(),
                        Description = string
                                      .Join(" ", new List <string>(singleBehaviorLines.Skip(1))
                        {
                            baseLine.Split("**")[2].Trim()
                        })
                                      .RemoveMarkdownCharacters(),
                        Restrictions = restrictions
                    };

                    monsterBehaviors.Add(monsterBehavior);
                }
                else
                {
                    var baseLine    = singleBehaviorLines.First(b => b.StartsWith("> **") || b.StartsWith(">**"));
                    var description = singleBehaviorLines.Skip(1).ToList();
                    description.Insert(0, baseLine.Split("***")[2].Trim());

                    var baseLineSplit = baseLine.Split(new[] { "***", "***" }, StringSplitOptions.None);
                    var parenIndex    = baseLineSplit[1].IndexOf('(');

                    var    name         = baseLineSplit[1].Trim().Replace(".", string.Empty);
                    string restrictions = null;
                    if (parenIndex != -1)
                    {
                        name = baseLineSplit[1].Remove(parenIndex).Trim();

                        var restrictionsSplit = baseLine.Split('(', ')');
                        if (restrictionsSplit.ElementAtOrDefault(1) != null)
                        {
                            restrictions = restrictionsSplit[1].Trim();
                        }
                    }

                    var monsterBehavior = new MonsterBehavior
                    {
                        MonsterBehaviorTypeEnum = behaviorType,
                        Name         = name,
                        Description  = string.Join(" ", description).RemoveMarkdownCharacters(),
                        Restrictions = restrictions
                    };

                    if (Regex.IsMatch(baseLine.Split("***")[2].Trim(), @"\*.+\*"))
                    {
                        if (behaviorType == MonsterBehaviorType.Action)
                        {
                            if (baseLine.Split("***")[2].Trim().Contains($"*{Localization.melee}", StringComparison.InvariantCultureIgnoreCase))
                            {
                                monsterBehavior.AttackTypeEnum = AttackType.MeleeWeapon;
                            }
                            else if (baseLine.Split("***")[2].Trim().Contains($"*{Localization.ranged}",
                                                                              StringComparison.InvariantCultureIgnoreCase))
                            {
                                monsterBehavior.AttackTypeEnum = AttackType.RangedWeapon;
                            }
                            else
                            {
                                monsterBehavior.AttackTypeEnum = AttackType.None;
                            }

                            var attackSplit      = baseLine.Split("***")[2].Trim().Split(',').Select(s => s.Trim()).ToList();
                            var hitSplit         = Regex.Split(baseLine.Split("***")[2].Trim(), Localization.MonsterHitSplitPattern);
                            var hitCommaSplit    = hitSplit.SafeAccess(0)?.Split(',')?.ToList() ?? new List <string>();
                            var hitSpaceSplit    = hitSplit.SafeAccess(1)?.Split(' ')?.ToList() ?? new List <string>();
                            var didParseAttBonus = int.TryParse(Regex.Match(attackSplit[0], @"-?\d+").Value, out var parsedAttBonus);
                            monsterBehavior.AttackBonus     = didParseAttBonus ? parsedAttBonus : 0;
                            monsterBehavior.Range           = attackSplit.ToArray().SafeAccess(1)?.Trim() ?? "";
                            monsterBehavior.NumberOfTargets = hitCommaSplit.ToArray().SafeAccess(2)?.Trim();

                            if (Regex.IsMatch(hitSplit.SafeAccess(1)?.Trim() ?? string.Empty, @"^\d+.*\(.*\)"))
                            {
                                monsterBehavior.Damage     = Regex.Match(hitSplit.SafeAccess(1) ?? string.Empty, @"-?\d+").Value.Trim();
                                monsterBehavior.DamageRoll = hitSplit.SafeAccess(1)?.Split('(', ')').ElementAtOrDefault(1)?.Trim();
                                if (hitSpaceSplit.FindIndex(f =>
                                                            f.Contains(Localization.damage, StringComparison.InvariantCultureIgnoreCase)) != -1)
                                {
                                    if (Enum.TryParse(hitSpaceSplit[hitSpaceSplit.FindIndex(f => f.Contains(Localization.damage, StringComparison.InvariantCultureIgnoreCase)) - 1],
                                                      true, out DamageType damageType) &&
                                        Enum.IsDefined(typeof(DamageType), damageType))
                                    {
                                        monsterBehavior.DamageTypeEnum = damageType;
                                    }
                                    else
                                    {
                                        monsterBehavior.DamageTypeEnum = DamageType.Unknown;
                                    }
                                }
                            }
                        }
                    }

                    monsterBehaviors.Add(monsterBehavior);
                }
            }

            return(monsterBehaviors);
        }