public float calcPawnSightRange(IntVec3 position, bool forTargeting, bool shouldMove) { if (pawn == null) { Log.Error("calcPawnSightRange performed on non pawn thing"); return(0); } float sightRange = 0f; initMap(); bool sleeping = !isMechanoid && pawn.CurJob != null && pawn.jobs.curDriver.asleep; if (!shouldMove && !sleeping && (pawnPather == null || !pawnPather.Moving)) { Verb attackVerb = null; if (pawn.CurJob != null) { JobDef jobDef = pawn.CurJob.def; if (jobDef == JobDefOf.ManTurret) { Building_Turret mannedTurret = pawn.CurJob.targetA.Thing as Building_Turret; if (mannedTurret != null) { attackVerb = mannedTurret.AttackVerb; } } else if (jobDef == JobDefOf.AttackStatic || jobDef == JobDefOf.AttackMelee || jobDef == JobDefOf.WaitCombat || jobDef == JobDefOf.Hunt) { if (pawn.equipment != null) { ThingWithComps primary = pawn.equipment.Primary; if (primary != null && primary.def.IsRangedWeapon) { attackVerb = primary.GetComp <CompEquippable>().PrimaryVerb; } } } } if (attackVerb != null && attackVerb.verbProps.range > baseViewRange && attackVerb.verbProps.requireLineOfSight && attackVerb.ownerEquipment.def.IsRangedWeapon) { float attackVerbRange = attackVerb.verbProps.range; if (baseViewRange < attackVerbRange) { int ticksStanding = Find.TickManager.TicksGame - lastMovementTick; float statValue = pawn.GetStatValue(StatDefOf.AimingDelayFactor, true); int ticksToSearch = (attackVerb.verbProps.warmupTime * statValue).SecondsToTicks() * Mathf.RoundToInt((attackVerbRange - baseViewRange) / 2); if (ticksStanding >= ticksToSearch) { sightRange = attackVerbRange * capacities.GetLevel(PawnCapacityDefOf.Sight); } else { int incValue = Mathf.RoundToInt((attackVerbRange - baseViewRange) * ((float)ticksStanding / ticksToSearch)); sightRange = (baseViewRange + incValue) * capacities.GetLevel(PawnCapacityDefOf.Sight); } } } } if (sightRange == 0f) { sightRange = baseViewRange * capacities.GetLevel(PawnCapacityDefOf.Sight); } if (!forTargeting && sleeping) { // Sleeping: sight reduced to 20% (if not for targeting). sightRange *= 0.2f; } // TODO: Apply moving penality? /*else if (!calcOnlyBase && pawnPather.Moving) { * // When moving, sight reduced to 90%s. * sightRange *= 0.9f; * } */ // Check if standing on an affect view object. List <CompAffectVision> compsAffectVision = mapCompSeenFog.compAffectVisionGrid[(position.z * mapSizeX) + position.x]; int compsCount = compsAffectVision.Count; for (int i = 0; i < compsCount; i++) { sightRange *= compsAffectVision[i].Props.fovMultiplier; } // Additional dark and weather debuff. if (!isMechanoid) { float currGlow = glowGrid.GameGlowAt(position); if (currGlow != 1f) { float darkModifier = 0.6f; // Each bionic eye reduce the dark debuff by 20. int hediffsCount = hediffs.Count; for (int i = 0; i < hediffsCount; i++) { if (hediffs[i].def == HediffDefOf.BionicEye) { darkModifier += 0.2f; } } // Apply only if to debuff. if (darkModifier < 1f) { // Adjusted to glow (100% full light - 60% dark). sightRange *= Mathf.Lerp(darkModifier, 1f, currGlow); } } if (!roofGrid.Roofed(position.x, position.z)) { float weatherFactor = weatherManager.CurWeatherAccuracyMultiplier; if (weatherFactor != 1f) { // Weather factor is applied by half. sightRange *= Mathf.Lerp(0.5f, 1f, weatherFactor); } } } // Mininum sight. if (sightRange < 1f) { return(1); } return(sightRange); }
private bool lightEnough(IntVec3 position) { return(glowGrid.GameGlowAt(position) >= RealFoWModSettings.minimumLightLevel); }