public int GetHeatResistance() { if (Owner.GetComponent <InventoryComponent>().TryGetSlotItem(EquipmentSlotDefines.Slots.GLOVES, itemComponent: out ClothingComponent gloves) | Owner.TryGetComponent(out SpeciesComponent speciesComponent)) { return(Math.Max(gloves?.HeatResistance ?? int.MinValue, speciesComponent?.HeatResistance ?? int.MinValue)); } return(int.MinValue); }
private void UpdatePanelCoverage(SolarPanelComponent panel) { IEntity entity = panel.Owner; // So apparently, and yes, I *did* only find this out later, // this is just a really fancy way of saying "Lambert's law of cosines". // ...I still think this explaination makes more sense. // In the 'sunRelative' coordinate system: // the sun is considered to be an infinite distance directly up. // this is the rotation of the panel relative to that. // directly upwards (theta = 0) = coverage 1 // left/right 90 degrees (abs(theta) = (pi / 2)) = coverage 0 // directly downwards (abs(theta) = pi) = coverage -1 // as TowardsSun + = CCW, // panelRelativeToSun should - = CW var panelRelativeToSun = entity.Transform.WorldRotation - TowardsSun; // essentially, given cos = X & sin = Y & Y is 'downwards', // then for the first 90 degrees of rotation in either direction, // this plots the lower-right quadrant of a circle. // now basically assume a line going from the negated X/Y to there, // and that's the hypothetical solar panel. // // since, again, the sun is considered to be an infinite distance upwards, // this essentially means Cos(panelRelativeToSun) is half of the cross-section, // and since the full cross-section has a max of 2, effectively-halving it is fine. // // as for when it goes negative, it only does that when (abs(theta) > pi) // and that's expected behavior. float coverage = (float)Math.Max(0, Math.Cos(panelRelativeToSun)); if (coverage > 0) { // Determine if the solar panel is occluded, and zero out coverage if so. // FIXME: The "Opaque" collision group doesn't seem to work right now. var ray = new CollisionRay(entity.Transform.WorldPosition, TowardsSun.ToVec(), (int)CollisionGroup.Opaque); var rayCastResults = IoCManager.Resolve <IPhysicsManager>().IntersectRay(entity.Transform.MapID, ray, SunOcclusionCheckDistance, entity); if (rayCastResults.Any()) { coverage = 0; } } // Total coverage calculated; apply it to the panel. panel.Coverage = coverage; }