public bool TryAttackEntity(IBattleEntity other) { bool canAttack = _owner.IsHostileTo(other) && CurrentAttack.CanTargetBeReached(_owner, other); if (canAttack) { PrepareAttack(CurrentAttack.FindAllReachableTargets(_owner)); } var defeated = StartAttack(); return(defeated.Contains(other)); }
public override List <IBattleEntity> FindAllReachableTargets(IBattleEntity source) { var allInMaxRange = _entityController.GetNearbyEntities(source.Coords, _rangeData.MaxRange); allInMaxRange.RemoveAll(x => !typeof(IBattleEntity).IsAssignableFrom(x.GetType())); var allBattlers = allInMaxRange.ConvertAll(x => (IBattleEntity)x); allBattlers.RemoveAll(x => !source.IsHostileTo(x)); allBattlers.RemoveAll(x => _mapController.Distance(x.Coords, source.Coords) < _rangeData.MinRange); allBattlers.RemoveAll(x => !CanTargetBeReached(source, x)); return(allBattlers); }
public override List <bool> GetReachableStateForCoords(IBattleEntity source, List <Vector2Int> coords) { var srcCoords = source.Coords; List <bool> visible = new List <bool>(); bool anyBlockingFound = false; for (int i = 0; i < coords.Count; ++i) { int dist = _mapController.Distance(srcCoords, coords[i]); if (dist < _rangeData.MinRange || dist > _rangeData.MaxRange) { visible.Add(false); continue; } if (anyBlockingFound) { visible.Add(false); continue; } TileBase tile = _mapController.GetTileAt(coords[i]); if (!_rangeData.AllowedTiles.Contains(tile)) { if (!anyBlockingFound) { anyBlockingFound = true; } else { visible.Add(false); continue; // Occluder found } } var others = _entityController.GetEntitiesAt(coords[i]); bool blockersFound = others.Exists(x => x.BlocksRanged(_rangeData.Piercing)); var hostiles = CollectionUtils.GetImplementors <BaseEntity, IBattleEntity>(others); hostiles.RemoveAll(x => !source.IsHostileTo(x)); visible.Add(hostiles.Count > 0 || !blockersFound); if (!anyBlockingFound && blockersFound) { anyBlockingFound = true; } } return(visible); }
public override List <IBattleEntity> FindTargetsAtCoords(IBattleEntity source, Vector2Int refCoords) { List <IBattleEntity> candidates = new List <IBattleEntity>(); Vector2Int srcCoords = source.Coords; Vector2Int tgtCoords = refCoords; var line = BoundedLine(srcCoords, tgtCoords); bool blockersFound = false; foreach (var lineCoord in line) { if (blockersFound) { break; // Occluder found } int distanceToSrc = _mapController.Distance(srcCoords, lineCoord); bool groundBlockFound = !_rangeData.AllowedTiles.Contains(_mapController.GetTileAt(lineCoord)); if (groundBlockFound) { if (!blockersFound) { blockersFound = true; } } var others = _entityController.GetEntitiesAt(lineCoord); var hostileOthers = CollectionUtils.GetImplementors <BaseEntity, IBattleEntity>(others); hostileOthers.RemoveAll(x => !source.IsHostileTo(x)); candidates.AddRange(hostileOthers); if (tgtCoords == lineCoord || others.Exists(x => x.BlocksRanged(_rangeData.Piercing))) { break; } } return(candidates); }
public override List <IBattleEntity> FindTargetsAtCoords(IBattleEntity source, Vector2Int refCoords) { if (!AtMeleeRange(source.Coords, refCoords)) { return(new List <IBattleEntity>()); } var filtered = _entityController.GetFilteredEntitiesAt <IBattleEntity>(refCoords).FindAll(x => source.IsHostileTo(x)); if (filtered.Count > 1 && ((SimpleMeleeAttackData)Data).SingleTarget) { filtered.RemoveRange(1, filtered.Count - 1); } return(filtered); }