private void initMap() { if (map != parent.Map) { if (map != null && lastFaction != null) { unseeSeenCells(lastFaction, lastFactionShownCells); } if (!disabled && mapCompSeenFog != null) { mapCompSeenFog.fowWatchers.Remove(this); } map = parent.Map; mapCompSeenFog = map.getMapComponentSeenFog(); thingGrid = map.thingGrid; glowGrid = map.glowGrid; roofGrid = map.roofGrid; weatherManager = map.weatherManager; lastFactionShownCells = mapCompSeenFog.getFactionShownCells(parent.Faction); if (!disabled) { mapCompSeenFog.fowWatchers.Add(this); } mapSizeX = map.Size.x; mapSizeZ = map.Size.z; } }
public static bool MouseoverReadoutOnGUI_Prefix(MouseoverReadout __instance) { if (Event.current.type != EventType.Repaint) { return(true); } if (Find.MainTabsRoot.OpenTab != null) { return(true); } IntVec3 c = UI.MouseCell(); if (!c.InBounds(Find.VisibleMap)) { return(true); } MapComponentSeenFog seenFog = Find.VisibleMap.getMapComponentSeenFog(); if (!c.Fogged(Find.VisibleMap) && (seenFog != null && !seenFog.knownCells[Find.VisibleMap.cellIndices.CellToIndex(c)])) { GenUI.DrawTextWinterShadow(new Rect(256f, (float)(UI.screenHeight - 256), -256f, 256f)); Text.Font = GameFont.Small; GUI.color = new Color(1f, 1f, 1f, 0.8f); Rect rect = new Rect(_MouseoverReadout.BotLeft.x, (float)UI.screenHeight - _MouseoverReadout.BotLeft.y, 999f, 999f); Widgets.Label(rect, "NotVisible".Translate()); GUI.color = Color.white; return(false); } return(true); }
public static void FillBeautyRelevantCells_Postfix(Map map) { MapComponentSeenFog mapCmq = map.getMapComponentSeenFog(); if (mapCmq != null) { BeautyUtility.beautyRelevantCells.RemoveAll(c => !mapCmq.knownCells[map.cellIndices.CellToIndex(c)]); } }
public static void ShouldShow_Postfix(ref bool __result) { if (__result) { Map map = Find.VisibleMap; MapComponentSeenFog mapCmq = map.getMapComponentSeenFog(); __result = (mapCmq == null || mapCmq.knownCells[map.cellIndices.CellToIndex(UI.MouseCell())]); } }
public static void Notify_Added_Postfix(ref Designation __instance) { if (__instance.def == DesignationDefOf.Mine && !__instance.target.HasThing) { MapComponentSeenFog mapCmq = __instance.designationManager.map.getMapComponentSeenFog(); if (mapCmq != null) { mapCmq.registerMineDesignation(__instance); } } }
private static bool seenByFaction(Thing thing, IntVec3 targetLoc) { MapComponentSeenFog seenFog = thing.Map.getMapComponentSeenFog(); if (seenFog != null) { return(seenFog.isShown(thing.Faction, targetLoc)); } return(true); }
public static void CellBoolDrawerGetBoolInt_Postfix(int index, ref FertilityGrid __instance, ref bool __result) { if (__result) { Map map = Traverse.Create(__instance).Field("map").GetValue <Map>(); MapComponentSeenFog mapCmq = map.getMapComponentSeenFog(); if (mapCmq != null) { __result = mapCmq.knownCells[index]; } } }
public static MapComponentSeenFog getMapComponentSeenFog(this Map map) { MapComponentSeenFog mapCompSeenFog = map.GetComponent <MapComponentSeenFog>(); // If still null, initialize it (old save). if (mapCompSeenFog == null) { mapCompSeenFog = new MapComponentSeenFog(map); map.components.Add(mapCompSeenFog); } return(mapCompSeenFog); }
public static bool CanDesignateCell_Prefix(ref IntVec3 c, ref Designator __instance, ref AcceptanceReport __result) { Map map = Traverse.Create(__instance).Property("Map").GetValue <Map>(); MapComponentSeenFog mapCmq = map.getMapComponentSeenFog(); if (mapCmq != null && c.InBounds(map) && !mapCmq.knownCells[map.cellIndices.CellToIndex(c)]) { __result = false; return(false); } return(true); }
public static void CanDesignateCell_Postfix(IntVec3 c, ref Designator __instance, ref AcceptanceReport __result) { if (!__result.Accepted) { Map map = Traverse.Create(__instance).Property("Map").GetValue <Map>(); if (map.designationManager.DesignationAt(c, DesignationDefOf.Mine) == null) { MapComponentSeenFog mapCmq = map.getMapComponentSeenFog(); if (mapCmq != null && c.InBounds(map) && !mapCmq.knownCells[map.cellIndices.CellToIndex(c)]) { __result = true; } } } }
public override void PostDeSpawn(Map map) { base.PostDeSpawn(map); // When de-spawn, if the thing was blocking the view, then trigger a FoV update for near objects. if (lastIsViewBlocker) { if (this.map != map) { this.map = map; mapCompSeenFog = map.getMapComponentSeenFog(); } updateViewBlockerCells(false); } }
private static bool fowInKnownCell(this Thing _this) { #if InternalProfile ProfilingUtils.startProfiling("FoWThingUtils.fowInKnownCell"); try { #endif MapComponentSeenFog mapComponent = _this.Map.getMapComponentSeenFog(); if (mapComponent != null) { bool[] knownCells = mapComponent.knownCells; int mapSizeX = mapComponent.mapSizeX; IntVec3 position = _this.Position; IntVec2 size = _this.def.size; if (size.x == 1 && size.z == 1) { return(mapComponent.knownCells[(position.z * mapSizeX) + position.x]); } else { CellRect occupiedRect = GenAdj.OccupiedRect(position, _this.Rotation, size); for (int x = occupiedRect.minX; x <= occupiedRect.maxX; x++) { for (int z = occupiedRect.minZ; z <= occupiedRect.maxZ; z++) { if (mapComponent.knownCells[(z * mapSizeX) + x]) { return(true); } } } } return(false); } return(true); #if InternalProfile } finally { ProfilingUtils.stopProfiling("FoWThingUtils.fowInKnownCell"); } #endif }
public static void ShouldSpawnMotesAt_Postfix(IntVec3 loc, Map map, ref bool __result) { if (!__result) { return; } // Cache map component for fast repeated retrieval var comp = lastUsedMapComponent; if (map != lastUsedMap) { lastUsedMap = map; comp = lastUsedMapComponent = map.GetComponent <MapComponentSeenFog>(); } __result = comp == null || comp.isShown(Faction.OfPlayer, loc.x, loc.z); }
private void updateIsViewBlocker() { bool isViewBlocker = blockLight && !b.CanBeSeenOver(); if (lastIsViewBlocker != isViewBlocker) { lastIsViewBlocker = isViewBlocker; if (map != parent.Map) { map = parent.Map; mapCompSeenFog = map.getMapComponentSeenFog(); } updateViewBlockerCells(isViewBlocker); } }
private void initMap() { if (map != parent.Map) { if (map != null && lastFaction != null) { unseeSeenCells(lastFaction, lastFactionShownCells); } map = parent.Map; mapCompSeenFog = map.getMapComponentSeenFog(); thingGrid = map.thingGrid; glowGrid = map.glowGrid; roofGrid = map.roofGrid; weatherManager = map.weatherManager; lastFactionShownCells = mapCompSeenFog.getFactionShownCells(parent.Faction); mapSizeX = map.Size.x; mapSizeZ = map.Size.z; } }
private void updateMeshes() { if (map != parent.Map) { map = parent.Map; mapComp = map.getMapComponentSeenFog(); } // Update meshes only if the map has been already initialized (sometime this is called when the map drawer isn't initialized yet). if (mapComp != null && mapComp.initialized) { MapMeshFlag allFlags = MapMeshFlag.Buildings | MapMeshFlag.BuildingsDamage | MapMeshFlag.GroundGlow | MapMeshFlag.PowerGrid | MapMeshFlag.Roofs | MapMeshFlag.Snow | MapMeshFlag.Terrain | MapMeshFlag.Things | MapMeshFlag.Zone; foreach (IntVec3 cell in parent.OccupiedRect().Cells) { if (cell.InBounds(map)) { map.mapDrawer.MapMeshDirty(cell, allFlags, false, false); } } } }
public static void CanDesignateCell_Postfix(ref IntVec3 c, ref Designator __instance, ref AcceptanceReport __result) { if (__result.Accepted) { Traverse traverse = Traverse.Create(__instance); CellRect cellRect = GenAdj.OccupiedRect(c, traverse.Field("placingRot").GetValue <Rot4>(), traverse.Property("PlacingDef").GetValue <BuildableDef>().Size); Map map = traverse.Property("Map").GetValue <Map>(); MapComponentSeenFog seenFog = map.getMapComponentSeenFog(); if (seenFog != null) { foreach (IntVec3 cell in cellRect) { if (!seenFog.knownCells[map.cellIndices.CellToIndex(cell)]) { __result = "CannotPlaceInUndiscovered".Translate(); return; } } } } }
public static bool fowInKnownCell(this Thing _this) { MapComponentSeenFog mapComponent = _this.Map.getMapComponentSeenFog(); if (mapComponent != null) { Faction playerFaction = Faction.OfPlayer; Map map = _this.Map; CellIndices cellIndices = map.cellIndices; foreach (IntVec3 cell in _this.OccupiedRect().Cells) { if (cell.InBounds(map) && mapComponent.knownCells[cellIndices.CellToIndex(cell)]) { return(true); } } return(false); } return(true); }
public static void computeFieldOfViewWithShadowCasting( int startX, int startY, int radius, bool[] viewBlockerCells, int maxX, int maxY, bool handleSeenAndCache, MapComponentSeenFog mapCompSeenFog, Faction faction, int[] factionShownCells, bool[] fovGrid, int fovGridMinX, int fovGridMinY, int fovGridWidth, bool[] oldFovGrid, int oldFovGridMinX, int oldFovGridMaxX, int oldFovGridMinY, int oldFovGridMaxY, int oldFovGridWidth, byte specificOctant = 255, int targetX = -1, int targetY = -1) { int r_r_4 = 4 * radius * radius; if (specificOctant == 255) { for (byte octant = 0; octant < 8; ++octant) { computeFieldOfViewInOctantZero( octant, fovGrid, fovGridMinX, fovGridMinY, fovGridWidth, oldFovGrid, oldFovGridMinX, oldFovGridMaxX, oldFovGridMinY, oldFovGridMaxY, oldFovGridWidth, radius, r_r_4, startX, startY, maxX, maxY, viewBlockerCells, handleSeenAndCache, mapCompSeenFog, faction, factionShownCells, targetX, targetY, 0, 1, 1, 1, 0); } } else { computeFieldOfViewInOctantZero( specificOctant, fovGrid, fovGridMinX, fovGridMinY, fovGridWidth, oldFovGrid, oldFovGridMinX, oldFovGridMaxX, oldFovGridMinY, oldFovGridMaxY, oldFovGridWidth, radius, r_r_4, startX, startY, maxX, maxY, viewBlockerCells, handleSeenAndCache, mapCompSeenFog, faction, factionShownCells, targetX, targetY, 0, 1, 1, 1, 0); } }
public void updateVisibility(bool forceCheck, bool forceUpdate = false) { if (!setupDone || Current.ProgramState == ProgramState.MapInitializing) { return; } #if InternalProfile //ProfilingUtils.startProfiling("CompHideFromPlayer.updateVisibility"); #endif Thing thing = base.parent; IntVec3 newPosition = thing.Position; Rot4 newRotation = thing.Rotation; if (thing != null && thing.Spawned && thing.Map != null && newPosition != iv3Invalid && (isOneCell || newRotation != r4Invalid)) { if (map != thing.Map) { map = thing.Map; fogGrid = map.fogGrid; mapCompSeenFog = thing.Map.getMapComponentSeenFog(); } else if (mapCompSeenFog == null) { mapCompSeenFog = thing.Map.getMapComponentSeenFog(); } if (mapCompSeenFog == null) { return; } if (forceCheck || !calculated || newPosition != lastPosition || (!isOneCell && newRotation != lastRotation)) { calculated = true; lastPosition = newPosition; lastRotation = newRotation; bool belongToPlayer = thing.Faction != null && thing.Faction.IsPlayer; if (mapCompSeenFog != null && !fogGrid.IsFogged(lastPosition)) { if (isSaveable && !saveCompressible) { if (!belongToPlayer) { if (isPawn && !hasPartShownToPlayer()) { compHiddenable.hide(); } else if (!isPawn && !seenByPlayer && !hasPartShownToPlayer()) { compHiddenable.hide(); } else { seenByPlayer = true; compHiddenable.show(); } } else { seenByPlayer = true; compHiddenable.show(); } } else if ((forceUpdate || !seenByPlayer) && hasPartShownToPlayer()) { seenByPlayer = true; compHiddenable.show(); } } } } #if InternalProfile //ProfilingUtils.stopProfiling("CompHideFromPlayer.updateVisibility"); #endif }
private static void computeFieldOfViewInOctantZero( byte octant, bool[] fovGrid, int fovGridMinX, int fovGridMinY, int fovGridWidth, bool[] oldFovGrid, int oldFovGridMinX, int oldFovGridMaxX, int oldFovGridMinY, int oldFovGridMaxY, int oldFovGridWidth, int radius, int r_r_4, int startX, int startY, int maxX, int maxY, bool[] viewBlockerCells, bool handleSeenAndCache, MapComponentSeenFog mapCompSeenFog, Faction faction, int[] factionShownCells, int targetX, int targetY, int x, int topVectorX, int topVectorY, int bottomVectorX, int bottomVectorY) { int topY; int bottomY; bool inRadius; bool currentIsOpaque; bool wasLastCellOpaque; bool lastCellCalcuated; int quotient; int remainder; int fogGridIdx; int oldFogGridIdx; int x2; int y2; int worldY = 0; int worldX = 0; bool firstIteration = true; while (firstIteration || !queue.Empty()) { if (!firstIteration) { ref ColumnPortion columnPortion = ref queue.Dequeue(); x = columnPortion.x; topVectorX = columnPortion.topVectorX; topVectorY = columnPortion.topVectorY; bottomVectorX = columnPortion.bottomVectorX; bottomVectorY = columnPortion.bottomVectorY; }
public void updatePosition() { if (!setupDone) { return; } Thing thing = base.parent; IntVec3 newPosition = thing.Position; Rot4 newRotation = thing.Rotation; if (thing != null && thing.Spawned && thing.Map != null && newPosition != iv3Invalid && (isOneCell || newRotation != r4Invalid) && (compHideFromPlayer != null || compAffectVision != null)) { if (map != thing.Map) { map = thing.Map; mapCompSeenFog = thing.Map.getMapComponentSeenFog(); } else if (mapCompSeenFog == null) { mapCompSeenFog = thing.Map.getMapComponentSeenFog(); } if (mapCompSeenFog == null) { return; } if (!calculated || newPosition != lastPosition || (!isOneCell && newRotation != lastRotation)) { calculated = true; if (isOneCell) { if (compHideFromPlayer != null) { mapCompSeenFog.deregisterCompHideFromPlayerPosition(compHideFromPlayer, lastPosition.x, lastPosition.z); mapCompSeenFog.registerCompHideFromPlayerPosition(compHideFromPlayer, newPosition.x, newPosition.z); } if (compAffectVision != null) { mapCompSeenFog.deregisterCompAffectVisionPosition(compAffectVision, lastPosition.x, lastPosition.z); mapCompSeenFog.registerCompAffectVisionPosition(compAffectVision, newPosition.x, newPosition.z); } } else { int z; int x; if (lastPosition != iv3Invalid && lastRotation != r4Invalid) { CellRect cellRect = GenAdj.OccupiedRect(lastPosition, lastRotation, size); for (z = cellRect.minZ; z <= cellRect.maxZ; z++) { for (x = cellRect.minX; x <= cellRect.maxX; x++) { if (compHideFromPlayer != null) { mapCompSeenFog.deregisterCompHideFromPlayerPosition(compHideFromPlayer, x, z); } if (compAffectVision != null) { mapCompSeenFog.deregisterCompAffectVisionPosition(compAffectVision, x, z); } } } } if (newPosition != iv3Invalid && newRotation != r4Invalid) { CellRect cellRect = GenAdj.OccupiedRect(newPosition, newRotation, size); for (z = cellRect.minZ; z <= cellRect.maxZ; z++) { for (x = cellRect.minX; x <= cellRect.maxX; x++) { if (compHideFromPlayer != null) { mapCompSeenFog.registerCompHideFromPlayerPosition(compHideFromPlayer, x, z); } if (compAffectVision != null) { mapCompSeenFog.registerCompAffectVisionPosition(compAffectVision, x, z); } } } } } lastPosition = newPosition; if (size.x != 1 || size.z != 1) { lastRotation = newRotation; } } } }
public override void Regenerate() { if (Current.ProgramState != ProgramState.Playing) { return; } if (pawnFog == null) { pawnFog = base.Map.getMapComponentSeenFog(); } if (pawnFog != null && pawnFog.initialized) { LayerSubMesh subMesh = base.GetSubMesh(MatBases.FogOfWar); bool firstGeneration; if (subMesh.mesh.vertexCount == 0) { firstGeneration = true; subMesh.mesh.MarkDynamic(); MakeBaseGeometry(this.section, subMesh, AltitudeLayer.FogOfWar); targetAlphas = new byte[subMesh.mesh.vertexCount]; alphaChangeTick = new int[subMesh.mesh.vertexCount]; meshColors = new Color32[subMesh.mesh.vertexCount]; } else { firstGeneration = false; } int colorIdx = 0; bool[] fogGrid = base.Map.fogGrid.fogGrid; if (this.factionShownGrid == null) { this.factionShownGrid = pawnFog.getFactionShownCells(Faction.OfPlayer); } short[] factionShownGrid = this.factionShownGrid; int[] playerShownCellsTick = pawnFog.playerVisibilityChangeTick; bool[] knownGrid = pawnFog.knownCells; int mapSizeX = base.Map.Size.x; CellRect cellRect = this.section.CellRect; int mapHeight = base.Map.Size.z - 1; int mapWidth = mapSizeX - 1; bool hasFoggedVerts = false; int cellIdx; int cellIdxN; int cellIdxS; int cellIdxE; int cellIdxW; int cellIdxSW; int cellIdxNW; int cellIdxNE; int cellIdxSE; bool cellKnown; bool adjCellKnown; byte alpha; int cellVisibilityChangeTick; for (int x = cellRect.minX; x <= cellRect.maxX; x++) { for (int z = cellRect.minZ; z <= cellRect.maxZ; z++) { cellIdx = z * mapSizeX + x; cellVisibilityChangeTick = playerShownCellsTick[cellIdx]; if (!fogGrid[cellIdx]) { if (factionShownGrid[cellIdx] == 0) { cellKnown = knownGrid[cellIdx]; for (int n = 0; n < 9; n++) { this.vertsNotShown[n] = true; this.vertsSeen[n] = cellKnown; } if (cellKnown) { cellIdxN = (z + 1) * mapSizeX + x; cellIdxS = (z - 1) * mapSizeX + x; cellIdxE = z * mapSizeX + (x + 1); cellIdxW = z * mapSizeX + (x - 1); cellIdxSW = (z - 1) * mapSizeX + (x - 1); cellIdxNW = (z + 1) * mapSizeX + (x - 1); cellIdxNE = (z + 1) * mapSizeX + (x + 1); cellIdxSE = (z - 1) * mapSizeX + (x + 1); if (z < mapHeight && !knownGrid[cellIdxN]) { this.vertsSeen[2] = false; this.vertsSeen[3] = false; this.vertsSeen[4] = false; } if (z > 0 && !knownGrid[cellIdxS]) { this.vertsSeen[6] = false; this.vertsSeen[7] = false; this.vertsSeen[0] = false; } if (x < mapWidth && !knownGrid[cellIdxE]) { this.vertsSeen[4] = false; this.vertsSeen[5] = false; this.vertsSeen[6] = false; } if (x > 0 && !knownGrid[cellIdxW]) { this.vertsSeen[0] = false; this.vertsSeen[1] = false; this.vertsSeen[2] = false; } if (z > 0 && x > 0 && !knownGrid[cellIdxSW]) { this.vertsSeen[0] = false; } if (z < mapHeight && x > 0 && !knownGrid[cellIdxNW]) { this.vertsSeen[2] = false; } if (z < mapHeight && x < mapWidth && !knownGrid[cellIdxNE]) { this.vertsSeen[4] = false; } if (z > 0 && x < mapWidth && !knownGrid[cellIdxSE]) { this.vertsSeen[6] = false; } } } else { for (int l = 0; l < 9; l++) { this.vertsNotShown[l] = false; this.vertsSeen[l] = false; } cellIdxN = (z + 1) * mapSizeX + x; cellIdxS = (z - 1) * mapSizeX + x; cellIdxE = z * mapSizeX + (x + 1); cellIdxW = z * mapSizeX + (x - 1); cellIdxSW = (z - 1) * mapSizeX + (x - 1); cellIdxNW = (z + 1) * mapSizeX + (x - 1); cellIdxNE = (z + 1) * mapSizeX + (x + 1); cellIdxSE = (z - 1) * mapSizeX + (x + 1); if (z < mapHeight && factionShownGrid[cellIdxN] == 0) { adjCellKnown = knownGrid[cellIdxN]; this.vertsNotShown[2] = true; this.vertsSeen[2] = adjCellKnown; this.vertsNotShown[3] = true; this.vertsSeen[3] = adjCellKnown; this.vertsNotShown[4] = true; this.vertsSeen[4] = adjCellKnown; } if (z > 0 && factionShownGrid[cellIdxS] == 0) { adjCellKnown = knownGrid[cellIdxS]; this.vertsNotShown[6] = true; this.vertsSeen[6] = adjCellKnown; this.vertsNotShown[7] = true; this.vertsSeen[7] = adjCellKnown; this.vertsNotShown[0] = true; this.vertsSeen[0] = adjCellKnown; } if (x < mapWidth && factionShownGrid[cellIdxE] == 0) { adjCellKnown = knownGrid[cellIdxE]; this.vertsNotShown[4] = true; this.vertsSeen[4] = adjCellKnown; this.vertsNotShown[5] = true; this.vertsSeen[5] = adjCellKnown; this.vertsNotShown[6] = true; this.vertsSeen[6] = adjCellKnown; } if (x > 0 && factionShownGrid[cellIdxW] == 0) { adjCellKnown = knownGrid[cellIdxW]; this.vertsNotShown[0] = true; this.vertsSeen[0] = adjCellKnown; this.vertsNotShown[1] = true; this.vertsSeen[1] = adjCellKnown; this.vertsNotShown[2] = true; this.vertsSeen[2] = adjCellKnown; } if (z > 0 && x > 0 && factionShownGrid[cellIdxSW] == 0) { adjCellKnown = knownGrid[cellIdxSW]; this.vertsNotShown[0] = true; this.vertsSeen[0] = adjCellKnown; } if (z < mapHeight && x > 0 && factionShownGrid[cellIdxNW] == 0) { adjCellKnown = knownGrid[cellIdxNW]; this.vertsNotShown[2] = true; this.vertsSeen[2] = adjCellKnown; } if (z < mapHeight && x < mapWidth && factionShownGrid[cellIdxNE] == 0) { adjCellKnown = knownGrid[cellIdxNE]; this.vertsNotShown[4] = true; this.vertsSeen[4] = adjCellKnown; } if (z > 0 && x < mapWidth && factionShownGrid[cellIdxSE] == 0) { adjCellKnown = knownGrid[cellIdxSE]; this.vertsNotShown[6] = true; this.vertsSeen[6] = adjCellKnown; } } } else { for (int k = 0; k < 9; k++) { this.vertsNotShown[k] = true; this.vertsSeen[k] = false; } } for (int m = 0; m < 9; m++) { if (this.vertsNotShown[m]) { if (vertsSeen[m]) { alpha = prefFogAlpha; } else { alpha = 255; } hasFoggedVerts = true; } else { alpha = 0; } if (!prefEnableFade || firstGeneration) { if (firstGeneration || meshColors[colorIdx].a != alpha) { meshColors[colorIdx] = new Color32(255, 255, 255, alpha); } if (prefEnableFade) { activeFogTransitions = true; targetAlphas[colorIdx] = alpha; alphaChangeTick[colorIdx] = cellVisibilityChangeTick; } } else if (targetAlphas[colorIdx] != alpha) { activeFogTransitions = true; targetAlphas[colorIdx] = alpha; alphaChangeTick[colorIdx] = cellVisibilityChangeTick; } colorIdx++; } } } if (!prefEnableFade || firstGeneration) { if (hasFoggedVerts) { subMesh.disabled = false; subMesh.mesh.colors32 = meshColors; } else { subMesh.disabled = true; } } } }
private static bool fovLineOfSight(IntVec3 sourceSq, IntVec3 targetLoc, Thing thing) { // If the thing is mannable, then use the manning pawn to perform the calculation. CompMannable compMannable = thing.TryGetComp <CompMannable>(); if (compMannable != null) { thing = compMannable.ManningPawn; // Apply interaction cell offset. sourceSq += (thing.Position - thing.InteractionCell); } // If not a pawn, then doesn't need a fov calculation. if (!(thing is Pawn)) { return(true); } MapComponentSeenFog seenFog = thing.Map.getMapComponentSeenFog(); CompMainComponent compMain = (CompMainComponent)thing.TryGetComp(CompMainComponent.COMP_DEF); CompFieldOfViewWatcher compFoV = compMain.compFieldOfViewWatcher; // If requires moving, calculate only the base sight. int sightRange = Mathf.RoundToInt(compFoV.calcPawnSightRange(sourceSq, true, !thing.Position.AdjacentToCardinal(sourceSq))); if (!sourceSq.InHorDistOf(targetLoc, sightRange)) { // If out of sightRange. return(false); } // Limit to needed octant. IntVec3 dir = targetLoc - sourceSq; byte octant; if (dir.x >= 0) { if (dir.z >= 0) { if (dir.x >= dir.z) { octant = 0; } else { octant = 1; } } else { if (dir.x >= -dir.z) { octant = 7; } else { octant = 6; } } } else { if (dir.z >= 0) { if (-dir.x >= dir.z) { octant = 3; } else { octant = 2; } } else { if (-dir.x >= -dir.z) { octant = 4; } else { octant = 5; } } } Map map = thing.Map; bool[] targetFound = new bool[1]; ShadowCaster.computeFieldOfViewWithShadowCasting(sourceSq.x, sourceSq.z, sightRange, seenFog.viewBlockerCells, map.Size.x, map.Size.z, false, null, null, null, targetFound, 0, 0, 0, null, 0, 0, 0, 0, 0, octant, targetLoc.x, targetLoc.z); return(targetFound[0]); }