/// <summary> /// Checks for cover along the flight path of the bullet, doesn't check for walls or plants, only intended for cover with partial fillPercent /// </summary> private bool GetPartialCoverBetween(Vector3 sourceLoc, Vector3 targetLoc, out Thing cover) { //Sanity check if (this.verbProps.projectileDef.projectile.flyOverhead) { cover = null; return(false); } sourceLoc.Scale(new Vector3(1, 0, 1)); targetLoc.Scale(new Vector3(1, 0, 1)); //Calculate segment vector and segment amount Vector3 shotVec = sourceLoc - targetLoc; //Vector from target to source Vector3 segmentVec = shotVec.normalized * segmentLength; float distToCheck = Mathf.Min(distToCheckForCover, shotVec.magnitude); //The distance to raycast float numSegments = distToCheck / segmentLength; //Raycast accross all segments to check for cover List <IntVec3> checkedCells = new List <IntVec3>(); Thing targetThing = GridsUtility.GetEdifice(targetLoc.ToIntVec3()); Thing newCover = null; for (int i = 0; i <= numSegments; i++) { IntVec3 cell = (targetLoc + segmentVec * i).ToIntVec3(); if (!checkedCells.Contains(cell)) { //Cover check, if cell has cover compare fillPercent and get the highest piece of cover, ignore if cover is the target (e.g. solar panels, crashed ship, etc) Thing coverAtCell = GridsUtility.GetCover(cell); if (coverAtCell != null && (targetThing == null || !coverAtCell.Equals(targetThing)) && (newCover == null || newCover.def.fillPercent < coverAtCell.def.fillPercent)) { newCover = coverAtCell; } } } cover = newCover; //Report success if found cover that is not a wall or plant return(cover != null && cover.def.Fillage != FillCategory.Full && cover.def.category != ThingCategory.Plant); //Don't care about trees }