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); }
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { MonsterBehavior behavior = animator.gameObject.GetComponent <MonsterBehavior>(); behavior.teleport(behavior.spawn); Debug.Log("teleport"); }
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(); } } }
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); } }
private void attack(int a, MonsterBehavior ai) { if (AttackRange >= Vector2.Distance(transform.position, target.transform.position)) { Vector2 dir = getTargetDir(ai); interact.Attack(a, dir); } }
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 }
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]; } }
private void move(MonsterBehavior ai) { if (InterVallCountdown <= 0) { Vector2 dir = getTargetDir(ai); rigidbody2D.velocity = dir * Speed; InterVallCountdown = movementIntervall; } }
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); } }
// 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(); }
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); }
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); }
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)); } }
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; }
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); }
protected override void monsterInit() { Vector3 dest = new Vector3(transform.position.x, transform.position.y, target.transform.position.z); MonsterBehavior.FollowStandingTargetStart(agent, dest); }
protected void Wander() { float destChangeRate = UnityEngine.Random.Range(minDestChangeRate, maxDestChangeRate); MonsterBehavior.Wander(agent, gameObject, mask, wanderRadius, destChangeRate, ref nextDestChange); }
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex) { MonsterBehavior behavior = animator.gameObject.GetComponent <MonsterBehavior>(); behavior.setMovement("player"); }
private void Start() { _behave = GetComponent <MonsterBehavior>(); }
private void Start() { monsterBehavior = GetComponentInParent <MonsterBehavior>(); }
protected override void monsterInit() { MonsterBehavior.FollowStandingTargetStart(agent, target.transform.position); }
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); }