using System; using System.Linq.Expressions; using System.Reflection; using Vintagestory.API.Common; namespace OrekiWoofsBees.Common; public static class CompatibilityUtil { private const string fruiting_bush_behavior_name = "BEBehaviorFruitingBush"; private const string b_state_field_name = "BState"; private const string growthstate_property_name = "Growthstate"; private const int flowering_growth_state_value = 2; private static System.Func? is_fruiting_bush_flowering_check; public static bool IsFruitingBushFlowering(this BlockEntityBehavior behavior) { var behaviorType = behavior.GetType(); if (!IsFruitingBushBehaviorType(behaviorType)) return false; var check = is_fruiting_bush_flowering_check ??= BuildIsFruitingBushFloweringCheck(behaviorType); return check(behavior); } private static bool IsFruitingBushBehaviorType(Type behaviorType) { for (var type = behaviorType; type is not null; type = type.BaseType) { if (type.Name == fruiting_bush_behavior_name) return true; } return false; } private static System.Func BuildIsFruitingBushFloweringCheck(Type behaviorType) { var bStateField = behaviorType.GetField(b_state_field_name, BindingFlags.Instance | BindingFlags.Public)!; var growthStateProperty = bStateField.FieldType.GetProperty(growthstate_property_name, BindingFlags.Instance | BindingFlags.Public)!; var behaviorParameter = Expression.Parameter(typeof(BlockEntityBehavior), "behavior"); var typedBehavior = Expression.Convert(behaviorParameter, behaviorType); var bState = Expression.Field(typedBehavior, bStateField); var growthState = Expression.Property(bState, growthStateProperty); var comparison = Expression.Equal( Expression.Convert(growthState, typeof(int)), Expression.Constant(flowering_growth_state_value)); return Expression.Lambda>(comparison, behaviorParameter).Compile(); } }