Omega Haxors Posted September 6, 2021 Report Share Posted September 6, 2021 (edited) I busted my nuts creating this, I figure someone here will appreciate it: *PESUDOCODE* SunVal = the current location's sunlight value (peaks at 22V) BlockVal = the current location's block value (at the feet) Time = the current time (10:30 for example, goes from 0:00 to 24:00) LightLevel = The output variable (in Lux) If you're holding a light source block in your main or offhand, set BlockVal to the greater: Current BlockVal, or the held item's light value Divide both SunVal and BlockVal by 22 (this returns the % value of how much light is available) Multiply SunVal and BlockVal by 10,000 (this is used to get the amount of energy in the light provided) SunVal and BlockVal are now represented in Lux Subtract 12:00 from the time (represent minutes as a fraction. For example 10:30 = 10.5) If the time results in a negative number, multiply it by -1 (negates negative values) Multiply Time by 0.1666 (returns a % value, from 0 to 200%) Ceiling at 100% (If over 100%, then set the value to 100% Any time before 6 and after 18 is "midnight" and you can safely assume a value of 1) Subtract Time by 1 (flips percentages, 0 becomes 1, 25% becomes 75% etc) Multiply SunVal by Time (finally, now you know how much daylight there is) If it's raining, divide SunVal by 10 (since the rainclouds block more light) Always divide BlockVal by 10 (aritifical light carries less energy than sunlight does) Compare SunVal and BlockVal. Set LightLevel to whichever one is higher. Edited September 13, 2021 by Omega Haxors Link to comment Share on other sites More sharing options...
Omega Haxors Posted September 13, 2021 Author Report Share Posted September 13, 2021 Time for the real code (as used in my mod) public float GetBlockLightAtEntity(Entity entity) { IBlockAccessor blocks = entity.World.BlockAccessor; float blocklight = 0; //init the variable SyncedEntityPos pos = entity.Pos; //init the location BlockPos blockpos = pos.AsBlockPos; //convert to block format blocklight = blocks.GetLightLevel(blockpos,EnumLightLevelType.OnlyBlockLight); //get the block light value at the location blocklight = blocklight / 22; //to convert to % value return blocklight; //Note: Non-sunlight sources are 1/3rd as strong, so be sure to divide them by 3 for apparant values } public float GetSunLightAtEntity(Entity entity, bool accountfordaytime = false) //comes with an optional variable to account for daylight { IBlockAccessor blocks = entity.World.BlockAccessor; float sunlight = 0; SyncedEntityPos pos = entity.Pos; BlockPos blockpos = pos.AsBlockPos; sunlight = blocks.GetLightLevel(blockpos,EnumLightLevelType.OnlySunLight); //get the sun light value at the location sunlight = sunlight / 22; if(accountfordaytime) //if true, calculations account for time as well { float hour = entity.World.Calendar.HourOfDay; hour = hour - 12; //offset time (noon is center) if(hour < 0){hour = hour * -1;}//negative is now positive hour = hour * 0.1666f; //convert to % if(hour > 1){hour = 1;} //any value over 100% is 100% hour = 1 - hour; //flips % value (75% -> 25%) sunlight = sunlight * hour; //reduce light level% by hour% bool israining = false; //Vintagestory.GameContent.GameEffectsPacket.RainAndFogActive; //it's broken. For now, rain will not affect light level. if(israining) { sunlight = sunlight * 0.9f; //10% less } } return sunlight; //as a % value, with 100% = a value of 22 } public float GetEntityLightAtEntity(Entity entity) //gets the Entity Light produced by the entity, such as when a player holds a torch or a spider lights up { float entitylight = 0; if(entity.LightHsv != null) { entitylight = Convert.ToSingle(entity.LightHsv.GetValue(2)); //annoying workaround to convert object to float } entitylight = entitylight / 22; return entitylight; } public float GetEntityLightAroundEntity(Entity centerentity) //gets the strongest Entity Light produced by nearby entities. This can include the center entity. { float strongestentitylight = 0; Entity[] entities = centerentity.World.GetEntitiesAround(centerentity.Pos.XYZ,9,9); foreach (Entity entity in entities) { float entitylight = 0; if(entity.LightHsv != null) //crashes if you don't { entitylight = Convert.ToSingle(entity.LightHsv.GetValue(2)); //annoying workaround to convert object to float entitylight = entitylight - Convert.ToSingle(centerentity.Pos.DistanceTo(entity.Pos.XYZ)); //calculate light fall-off over distance strongestentitylight = Math.Max(strongestentitylight,entitylight); //pick the strongest light source } strongestentitylight = strongestentitylight / 22; } return strongestentitylight; } Link to comment Share on other sites More sharing options...
Omega Haxors Posted September 13, 2021 Author Report Share Posted September 13, 2021 If you need any help implementing this or want to know what something does, feel free to ask. Link to comment Share on other sites More sharing options...
Recommended Posts