private static Matrix4x4 RenderProp(ushort refId, float refAngleRad, RenderManager.CameraInfo cameraInfo, PropInfo propInfo, Color propColor, Vector3 position, Vector4 dataVector, int idx, Vector3 rotation, Vector3 scale, int layerMask, out bool rendered, InstanceID propRenderID2) { rendered = false; var randomizer = new Randomizer((refId << 6) | (idx + 32)); Matrix4x4 matrix = default; matrix.SetTRS(position, Quaternion.AngleAxis(rotation.y + (refAngleRad * Mathf.Rad2Deg), Vector3.down) * Quaternion.AngleAxis(rotation.x, Vector3.left) * Quaternion.AngleAxis(rotation.z, Vector3.back), scale); if (propInfo != null) { propInfo = propInfo.GetVariation(ref randomizer); if (cameraInfo.CheckRenderDistance(position, propInfo.m_maxRenderDistance * scale.sqrMagnitude)) { int oldLayerMask = cameraInfo.m_layerMask; float oldRenderDist = propInfo.m_lodRenderDistance; propInfo.m_lodRenderDistance *= scale.sqrMagnitude; cameraInfo.m_layerMask = 0x7FFFFFFF; try { PropInstance.RenderInstance(cameraInfo, propInfo, propRenderID2, matrix, position, scale.y, refAngleRad + (rotation.y * Mathf.Deg2Rad), propColor, dataVector, true); } finally { propInfo.m_lodRenderDistance = oldRenderDist; cameraInfo.m_layerMask = oldLayerMask; } rendered = true; } } return(matrix); }
public static bool RenderDestroyedInstancePrefix(NetLane __instance, RenderManager.CameraInfo cameraInfo, ushort segmentID, uint laneID, NetInfo netInfo, NetInfo.Lane laneInfo, NetNode.Flags startFlags, NetNode.Flags endFlags, Color startColor, Color endColor, float startAngle, float endAngle, bool invert, int layerMask, Vector4 objectIndex1, Vector4 objectIndex2, ref RenderManager.Instance data, ref int propIndex) { NetLaneProps laneProps = laneInfo.m_laneProps; if (laneProps != null && laneProps.m_props != null) { bool flag = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward; bool flag2 = flag != invert; if (flag) { NetNode.Flags flags = startFlags; startFlags = endFlags; endFlags = flags; } int num = laneProps.m_props.Length; for (int i = 0; i < num; i++) { NetLaneProps.Prop prop = laneProps.m_props[i]; if (__instance.m_length < prop.m_minLength) { continue; } int num2 = 2; if (prop.m_repeatDistance > 1f) { num2 *= Mathf.Max(1, Mathf.RoundToInt(__instance.m_length / prop.m_repeatDistance)); } int num3 = propIndex; if (propIndex != -1) { propIndex = num3 + (num2 + 1 >> 1); } if (!prop.CheckFlags((NetLane.Flags)__instance.m_flags, startFlags, endFlags)) { continue; } float num4 = prop.m_segmentOffset * 0.5f; if (__instance.m_length != 0f) { num4 = Mathf.Clamp(num4 + prop.m_position.z / __instance.m_length, -0.5f, 0.5f); } if (flag2) { num4 = 0f - num4; } PropInfo finalProp = prop.m_finalProp; if (!(finalProp != null) || (layerMask & (1 << finalProp.m_prefabDataLayer)) == 0) { continue; } Color color = (prop.m_colorMode != NetLaneProps.ColorMode.EndState) ? startColor : endColor; Randomizer r = new Randomizer((int)laneID + i); for (int j = 1; j <= num2; j += 2) { if (r.Int32(100u) >= prop.m_probability) { continue; } float num5 = num4 + (float)j / (float)num2; PropInfo variation = finalProp.GetVariation(ref r); float scale = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f; if (prop.m_colorMode == NetLaneProps.ColorMode.Default) { color = variation.GetColor(ref r); } if (!variation.m_isDecal && !variation.m_surviveCollapse) { continue; } Vector3 vector = __instance.m_bezier.Position(num5); if (propIndex != -1) { vector.y = (float)(int)data.m_extraData.GetUShort(num3++) * 0.015625f; } vector.y += prop.m_position.y; if (!cameraInfo.CheckRenderDistance(vector, variation.m_maxRenderDistance)) { continue; } Vector3 vector2 = __instance.m_bezier.Tangent(num5); if (!(vector2 != Vector3.zero)) { continue; } if (flag2) { vector2 = -vector2; } vector2.y = 0f; if (prop.m_position.x != 0f) { vector2 = Vector3.Normalize(vector2); vector.x += vector2.z * prop.m_position.x; vector.z -= vector2.x * prop.m_position.x; } float num6 = Mathf.Atan2(vector2.x, 0f - vector2.z); if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f) { float num7 = endAngle - startAngle; if (num7 > (float)Math.PI) { num7 -= (float)Math.PI * 2f; } if (num7 < -(float)Math.PI) { num7 += (float)Math.PI * 2f; } float num8 = startAngle + num7 * num5; num7 = num8 - num6; if (num7 > (float)Math.PI) { num7 -= (float)Math.PI * 2f; } if (num7 < -(float)Math.PI) { num7 += (float)Math.PI * 2f; } num6 += num7 * prop.m_cornerAngle; if (num7 != 0f && prop.m_position.x != 0f) { float num9 = Mathf.Tan(num7); vector.x += vector2.x * num9 * prop.m_position.x; vector.z += vector2.z * num9 * prop.m_position.x; } } Vector4 objectIndex3 = (!(num5 > 0.5f)) ? objectIndex1 : objectIndex2; num6 += prop.m_angle * ((float)Math.PI / 180f); InstanceID id = default(InstanceID); id.NetSegment = segmentID; #if UseTask Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true)); #else PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true); #endif } } } if ((laneInfo.m_laneType & (NetInfo.LaneType.Vehicle | NetInfo.LaneType.Parking | NetInfo.LaneType.CargoVehicle | NetInfo.LaneType.TransportVehicle)) == 0 && ((laneInfo.m_laneType & NetInfo.LaneType.Pedestrian) == 0 || netInfo.m_vehicleTypes != 0)) { return(false); } bool flag3 = (laneInfo.m_vehicleType & ~VehicleInfo.VehicleType.Bicycle) == 0 || laneInfo.m_verticalOffset >= 0.5f; Randomizer r2 = new Randomizer(laneID); int num10 = Mathf.RoundToInt(__instance.m_length * 0.07f); for (int k = 0; k < num10; k++) { PropInfo randomPropInfo = Singleton <PropManager> .instance.GetRandomPropInfo(ref r2, ItemClass.Service.Road); randomPropInfo = randomPropInfo.GetVariation(ref r2); float num11 = randomPropInfo.m_minScale + (float)r2.Int32(10000u) * (randomPropInfo.m_maxScale - randomPropInfo.m_minScale) * 0.0001f; Color color2 = randomPropInfo.GetColor(ref r2); float num12 = (float)r2.Int32(1000u) * 0.001f; float angle = (float)r2.Int32(1000u) * 0.006283186f; if (!randomPropInfo.m_isDecal) { if (flag3) { continue; } if (netInfo.m_netAI.IsOverground()) { float num13 = netInfo.m_halfWidth - Mathf.Abs(laneInfo.m_position); float num14 = Mathf.Max(randomPropInfo.m_generatedInfo.m_size.x, randomPropInfo.m_generatedInfo.m_size.z) * num11 * 0.5f - 0.5f; if (num13 < num14) { continue; } } } Vector3 position = __instance.m_bezier.Position(num12); Vector4 objectIndex4 = (!(num12 > 0.5f)) ? objectIndex1 : objectIndex2; InstanceID id2 = default(InstanceID); id2.NetSegment = segmentID; if (!randomPropInfo.m_requireHeightMap) { #if UseTask Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, randomPropInfo, id2, position, num11, angle, color2, objectIndex4, active: true)); #else PropInstance.RenderInstance(cameraInfo, randomPropInfo, id2, position, num11, angle, color2, objectIndex4, active: true); #endif } } return(false); }
public static bool RenderInstancePrefix(NetLane __instance, RenderManager.CameraInfo cameraInfo, ushort segmentID, uint laneID, NetInfo.Lane laneInfo, NetNode.Flags startFlags, NetNode.Flags endFlags, Color startColor, Color endColor, float startAngle, float endAngle, bool invert, int layerMask, Vector4 objectIndex1, Vector4 objectIndex2, ref RenderManager.Instance data, ref int propIndex) { NetLaneProps laneProps = laneInfo.m_laneProps; if (!(laneProps != null) || laneProps.m_props == null) { return(false); } bool flag = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward; bool flag2 = flag != invert; if (flag) { NetNode.Flags flags = startFlags; startFlags = endFlags; endFlags = flags; } Texture _HeightMap = null; Vector4 _HeightMapping = Vector4.zero; Vector4 _SurfaceMapping = Vector4.zero; Texture _HeightMap2 = null; Vector4 _HeightMapping2 = Vector4.zero; Vector4 _SurfaceMapping2 = Vector4.zero; int num = laneProps.m_props.Length; for (int i = 0; i < num; i++) { NetLaneProps.Prop prop = laneProps.m_props[i]; if (__instance.m_length < prop.m_minLength) { continue; } int num2 = 2; if (prop.m_repeatDistance > 1f) { num2 *= Mathf.Max(1, Mathf.RoundToInt(__instance.m_length / prop.m_repeatDistance)); } int num3 = propIndex; if (propIndex != -1) { propIndex = num3 + (num2 + 1 >> 1); } if (!prop.CheckFlags((NetLane.Flags)__instance.m_flags, startFlags, endFlags)) { continue; } float num4 = prop.m_segmentOffset * 0.5f; if (__instance.m_length != 0f) { num4 = Mathf.Clamp(num4 + prop.m_position.z / __instance.m_length, -0.5f, 0.5f); } if (flag2) { num4 = 0f - num4; } PropInfo finalProp = prop.m_finalProp; if (finalProp != null && (layerMask & (1 << finalProp.m_prefabDataLayer)) != 0) { Color color = (prop.m_colorMode != NetLaneProps.ColorMode.EndState) ? startColor : endColor; Randomizer r = new Randomizer((int)laneID + i); for (int j = 1; j <= num2; j += 2) { if (r.Int32(100u) >= prop.m_probability) { continue; } float num5 = num4 + (float)j / (float)num2; PropInfo variation = finalProp.GetVariation(ref r); float scale = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f; if (prop.m_colorMode == NetLaneProps.ColorMode.Default) { color = variation.GetColor(ref r); } Vector3 vector = __instance.m_bezier.Position(num5); if (propIndex != -1) { vector.y = (float)(int)data.m_extraData.GetUShort(num3++) * 0.015625f; } vector.y += prop.m_position.y; if (!cameraInfo.CheckRenderDistance(vector, variation.m_maxRenderDistance)) { continue; } Vector3 vector2 = __instance.m_bezier.Tangent(num5); if (!(vector2 != Vector3.zero)) { continue; } if (flag2) { vector2 = -vector2; } vector2.y = 0f; if (prop.m_position.x != 0f) { vector2 = Vector3.Normalize(vector2); vector.x += vector2.z * prop.m_position.x; vector.z -= vector2.x * prop.m_position.x; } float num6 = Mathf.Atan2(vector2.x, 0f - vector2.z); if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f) { float num7 = endAngle - startAngle; if (num7 > (float)Math.PI) { num7 -= (float)Math.PI * 2f; } if (num7 < -(float)Math.PI) { num7 += (float)Math.PI * 2f; } float num8 = startAngle + num7 * num5; num7 = num8 - num6; if (num7 > (float)Math.PI) { num7 -= (float)Math.PI * 2f; } if (num7 < -(float)Math.PI) { num7 += (float)Math.PI * 2f; } num6 += num7 * prop.m_cornerAngle; if (num7 != 0f && prop.m_position.x != 0f) { float num9 = Mathf.Tan(num7); vector.x += vector2.x * num9 * prop.m_position.x; vector.z += vector2.z * num9 * prop.m_position.x; } } Vector4 objectIndex3 = (!(num5 > 0.5f)) ? objectIndex1 : objectIndex2; num6 += prop.m_angle * ((float)Math.PI / 180f); InstanceID id = default(InstanceID); id.NetSegment = segmentID; if (variation.m_requireWaterMap) { if (_HeightMap == null) { Singleton <TerrainManager> .instance.GetHeightMapping(Singleton <NetManager> .instance.m_segments.m_buffer[segmentID].m_middlePosition, out _HeightMap, out _HeightMapping, out _SurfaceMapping); } if (_HeightMap2 == null) { Singleton <TerrainManager> .instance.GetWaterMapping(Singleton <NetManager> .instance.m_segments.m_buffer[segmentID].m_middlePosition, out _HeightMap2, out _HeightMapping2, out _SurfaceMapping2); } #if UseTask Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true, _HeightMap, _HeightMapping, _SurfaceMapping, _HeightMap2, _HeightMapping2, _SurfaceMapping2)); #else PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true, _HeightMap, _HeightMapping, _SurfaceMapping, _HeightMap2, _HeightMapping2, _SurfaceMapping2); #endif } else if (!variation.m_requireHeightMap) { #if UseTask Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true)); #else PropInstance.RenderInstance(cameraInfo, variation, id, vector, scale, num6, color, objectIndex3, active: true); #endif } } } TreeInfo finalTree = prop.m_finalTree; if (!(finalTree != null) || (layerMask & (1 << finalTree.m_prefabDataLayer)) == 0) { continue; } Randomizer r2 = new Randomizer((int)laneID + i); for (int k = 1; k <= num2; k += 2) { if (r2.Int32(100u) >= prop.m_probability) { continue; } float t = num4 + (float)k / (float)num2; TreeInfo variation2 = finalTree.GetVariation(ref r2); float scale2 = variation2.m_minScale + (float)r2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f; float brightness = variation2.m_minBrightness + (float)r2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f; Vector3 position = __instance.m_bezier.Position(t); if (propIndex != -1) { position.y = (float)(int)data.m_extraData.GetUShort(num3++) * 0.015625f; } position.y += prop.m_position.y; if (prop.m_position.x != 0f) { Vector3 vector3 = __instance.m_bezier.Tangent(t); if (flag2) { vector3 = -vector3; } vector3.y = 0f; vector3 = Vector3.Normalize(vector3); position.x += vector3.z * prop.m_position.x; position.z -= vector3.x * prop.m_position.x; } #if UseTask Patcher.Dispatcher.Add(() => TreeInstance.RenderInstance(cameraInfo, variation2, position, scale2, brightness, RenderManager.DefaultColorLocation)); #else TreeInstance.RenderInstance(cameraInfo, variation2, position, scale2, brightness, RenderManager.DefaultColorLocation); #endif } } return(false); }
public void PopulateGroupData( ushort segmentID, uint laneID, NetInfo.Lane laneInfo, bool destroyed, NetNode.Flags startFlags, NetNode.Flags endFlags, float startAngle, float endAngle, bool invert, bool terrainHeight, int layer, ref int vertexIndex, ref int triangleIndex, Vector3 groupPosition, RenderGroup.MeshData data, ref Vector3 min, ref Vector3 max, ref float maxRenderDistance, ref float maxInstanceDistance, ref bool hasProps) { NetLaneProps laneProps = laneInfo.m_laneProps; if (laneProps?.m_props == null) { return; } bool backward = (laneInfo.m_finalDirection & NetInfo.Direction.Both) == NetInfo.Direction.Backward || (laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == NetInfo.Direction.AvoidForward; bool reverse = backward != invert; if (backward) //swap { NetNode.Flags flags = startFlags; startFlags = endFlags; endFlags = flags; } int nProps = laneProps.m_props.Length; for (int i = 0; i < nProps; i++) { NetLaneProps.Prop prop = laneProps.m_props[i]; if (!prop.CheckFlags(m_flags, startFlags, endFlags) || m_length < prop.m_minLength) { continue; } int repeatCountTimes2 = 2; if (prop.m_repeatDistance > 1f) { repeatCountTimes2 *= Mathf.Max(1, Mathf.RoundToInt(m_length / prop.m_repeatDistance)); } float halfSegmentOffset = prop.m_segmentOffset * 0.5f; if (m_length != 0f) { halfSegmentOffset = Mathf.Clamp(halfSegmentOffset + prop.m_position.z / m_length, -0.5f, 0.5f); } if (reverse) { halfSegmentOffset = 0f - halfSegmentOffset; } PropInfo finalProp = prop.m_finalProp; if ((object)finalProp != null) { hasProps = true; if (finalProp.m_prefabDataLayer == layer || finalProp.m_effectLayer == layer) { Color color = Color.white; Randomizer r = new Randomizer((int)laneID + i); for (int j = 1; j <= repeatCountTimes2; j += 2) { if (r.Int32(100u) >= prop.m_probability) { continue; } float t = halfSegmentOffset + (float)j / (float)repeatCountTimes2; PropInfo variation = finalProp.GetVariation(ref r); float scale = variation.m_minScale + (float)r.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f; if (prop.m_colorMode == NetLaneProps.ColorMode.Default) { color = variation.GetColor(ref r); } if (!variation.m_isDecal && destroyed) { continue; } Vector3 pos = m_bezier.Position(t); Vector3 tan = m_bezier.Tangent(t); if (!(tan != Vector3.zero)) { continue; } if (reverse) { tan = -tan; } tan.y = 0f; if (prop.m_position.x != 0f) { tan = Vector3.Normalize(tan); pos.x += tan.z * prop.m_position.x; pos.z -= tan.x * prop.m_position.x; } float normalAngle = Mathf.Atan2(tan.x, 0f - tan.z); if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f) { float angleDiff = endAngle - startAngle; if (angleDiff > Mathf.PI) { angleDiff -= Mathf.PI * 2f; } if (angleDiff < -Mathf.PI) { angleDiff += Mathf.PI * 2f; } var angle2 = startAngle + angleDiff * t - normalAngle; if (angle2 > Mathf.PI) { angle2 -= Mathf.PI * 2f; } if (angle2 < -Mathf.PI) { angle2 += Mathf.PI * 2f; } normalAngle += angle2 * prop.m_cornerAngle; if (angle2 != 0f && prop.m_position.x != 0f) { float d = Mathf.Tan(angle2); pos.x += tan.x * d * prop.m_position.x; pos.z += tan.z * d * prop.m_position.x; } } if (terrainHeight) { if (variation.m_requireWaterMap) { pos.y = Singleton <TerrainManager> .instance.SampleRawHeightSmoothWithWater(pos, timeLerp : false, 0f); } else { pos.y = Singleton <TerrainManager> .instance.SampleDetailHeight(pos); } } pos.y += prop.m_position.y; InstanceID id = default(InstanceID); id.NetSegment = segmentID; PropInstance.PopulateGroupData(angle: normalAngle + prop.m_angle * (Mathf.PI / 180f), info: variation, layer: layer, id: id, position: pos, scale: scale, color: color, vertexIndex: ref vertexIndex, triangleIndex: ref triangleIndex, groupPosition: groupPosition, data: data, min: ref min, max: ref max, maxRenderDistance: ref maxRenderDistance, maxInstanceDistance: ref maxInstanceDistance); } } } if (destroyed) { continue; } TreeInfo finalTree = prop.m_finalTree; if ((object)finalTree == null) { continue; } hasProps = true; if (finalTree.m_prefabDataLayer != layer) { continue; } Randomizer r2 = new Randomizer((int)laneID + i); for (int k = 1; k <= repeatCountTimes2; k += 2) { if (r2.Int32(100u) >= prop.m_probability) { continue; } float t = halfSegmentOffset + (float)k / (float)repeatCountTimes2; TreeInfo variation2 = finalTree.GetVariation(ref r2); float scale2 = variation2.m_minScale + (float)r2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f; float brightness = variation2.m_minBrightness + (float)r2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f; Vector3 vector3 = m_bezier.Position(t); if (prop.m_position.x != 0f) { Vector3 vector4 = m_bezier.Tangent(t); if (reverse) { vector4 = -vector4; } vector4.y = 0f; vector4 = Vector3.Normalize(vector4); vector3.x += vector4.z * prop.m_position.x; vector3.z -= vector4.x * prop.m_position.x; } if (terrainHeight) { vector3.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector3); } vector3.y += prop.m_position.y; TreeInstance.PopulateGroupData(variation2, vector3, scale2, brightness, RenderManager.DefaultColorLocation, ref vertexIndex, ref triangleIndex, groupPosition, data, ref min, ref max, ref maxRenderDistance, ref maxInstanceDistance); } } }
public void RenderInstance( RenderManager.CameraInfo cameraInfo, ushort segmentID, uint laneID, NetInfo.Lane laneInfo, NetNode.Flags startFlags, NetNode.Flags endFlags, Color startColor, Color endColor, float startAngle, float endAngle, bool invert, int layerMask, Vector4 objectIndex1, Vector4 objectIndex2, ref RenderManager.Instance data, ref int propIndex) { NetLaneProps laneProps = laneInfo.m_laneProps; if (laneProps != null && laneProps.m_props != null) { bool backward = (byte)(laneInfo.m_finalDirection & NetInfo.Direction.Both) == 2 || (byte)(laneInfo.m_finalDirection & NetInfo.Direction.AvoidBoth) == 11; bool reverse = backward != invert; if (backward) //swap { NetNode.Flags flags = startFlags; startFlags = endFlags; endFlags = flags; } Texture texture = null; Vector4 zero = Vector4.zero; Vector4 zero2 = Vector4.zero; Texture texture2 = null; Vector4 zero3 = Vector4.zero; Vector4 zero4 = Vector4.zero; int nProps = laneProps.m_props.Length; for (int i = 0; i < nProps; i++) { NetLaneProps.Prop prop = laneProps.m_props[i]; if (this.m_length >= prop.m_minLength) { int repeatCountTimes2 = 2; if (prop.m_repeatDistance > 1f) { repeatCountTimes2 *= Mathf.Max(1, Mathf.RoundToInt(this.m_length / prop.m_repeatDistance)); } int currentPropIndex = propIndex; if (propIndex != -1) { propIndex = currentPropIndex + (repeatCountTimes2 + 1) >> 1; // div 2 } if (prop.CheckFlags(this.m_flags, startFlags, endFlags)) { float halfSegmentOffset = prop.m_segmentOffset * 0.5f; if (this.m_length != 0f) { halfSegmentOffset = Mathf.Clamp(halfSegmentOffset + prop.m_position.z / this.m_length, -0.5f, 0.5f); } if (reverse) { halfSegmentOffset = -halfSegmentOffset; } PropInfo finalProp = prop.m_finalProp; if (finalProp != null && (layerMask & 1 << finalProp.m_prefabDataLayer) != 0) { Color color = (prop.m_colorMode != NetLaneProps.ColorMode.EndState) ? startColor : endColor; Randomizer randomizer = new Randomizer((int)(laneID + (uint)i)); for (int j = 1; j <= repeatCountTimes2; j += 2) { if (randomizer.Int32(100u) < prop.m_probability) { float t = halfSegmentOffset + (float)j / (float)repeatCountTimes2; PropInfo variation = finalProp.GetVariation(ref randomizer); float scale = variation.m_minScale + (float)randomizer.Int32(10000u) * (variation.m_maxScale - variation.m_minScale) * 0.0001f; if (prop.m_colorMode == NetLaneProps.ColorMode.Default) { color = variation.GetColor(ref randomizer); } Vector3 pos = this.m_bezier.Position(t); if (propIndex != -1) { pos.y = (float)data.m_extraData.GetUShort(currentPropIndex++) * 0.015625f; } pos.y += prop.m_position.y; if (cameraInfo.CheckRenderDistance(pos, variation.m_maxRenderDistance)) { Vector3 tan = this.m_bezier.Tangent(t); if (tan != Vector3.zero) { if (reverse) { tan = -tan; } Vector3 normalXZ = new Vector3 { x = tan.z, z = -tan.x }; if (prop.m_position.x != 0f) { tan.Normalize(); normalXZ.Normalize(); pos += normalXZ * prop.m_position.x; } float normalAngle = Mathf.Atan2(normalXZ.z, normalXZ.x); if (prop.m_cornerAngle != 0f || prop.m_position.x != 0f) { float angleDiff = endAngle - startAngle; if (angleDiff > Mathf.PI) { angleDiff -= 2 * Mathf.PI; } if (angleDiff < -Mathf.PI) { angleDiff += 2 * Mathf.PI; } float currentAngle = startAngle + angleDiff * t; float angle2 = currentAngle - normalAngle; if (angle2 > Mathf.PI) { angle2 -= 2 * Mathf.PI; } if (angle2 < -Mathf.PI) { angle2 += 2 * Mathf.PI; } normalAngle += angle2 * prop.m_cornerAngle; if (angle2 != 0f && prop.m_position.x != 0f) { float d = Mathf.Tan(angle2); pos.x += tan.x * d * prop.m_position.x; pos.z += tan.z * d * prop.m_position.x; } } Vector4 objectIndex3 = (t <= 0.5f) ? objectIndex1 : objectIndex2; normalAngle += prop.m_angle * 0.0174532924f; InstanceID id = default(InstanceID); id.NetSegment = segmentID; if (variation.m_requireWaterMap) { if (texture == null) { Singleton <TerrainManager> .instance.GetHeightMapping(Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID].m_middlePosition, out texture, out zero, out zero2); } if (texture2 == null) { Singleton <TerrainManager> .instance.GetWaterMapping(Singleton <NetManager> .instance.m_segments.m_buffer[(int)segmentID].m_middlePosition, out texture2, out zero3, out zero4); } PropInstance.RenderInstance(cameraInfo, variation, id, pos, scale, normalAngle, color, objectIndex3, true, texture, zero, zero2, texture2, zero3, zero4); } else if (!variation.m_requireHeightMap) { PropInstance.RenderInstance(cameraInfo, variation, id, pos, scale, normalAngle, color, objectIndex3, true); } } } } } } TreeInfo finalTree = prop.m_finalTree; if (finalTree != null && (layerMask & 1 << finalTree.m_prefabDataLayer) != 0) { Randomizer randomizer2 = new Randomizer((int)(laneID + (uint)i)); for (int k = 1; k <= repeatCountTimes2; k += 2) { if (randomizer2.Int32(100u) < prop.m_probability) { float t = halfSegmentOffset + (float)k / (float)repeatCountTimes2; TreeInfo variation2 = finalTree.GetVariation(ref randomizer2); float scale2 = variation2.m_minScale + (float)randomizer2.Int32(10000u) * (variation2.m_maxScale - variation2.m_minScale) * 0.0001f; float brightness = variation2.m_minBrightness + (float)randomizer2.Int32(10000u) * (variation2.m_maxBrightness - variation2.m_minBrightness) * 0.0001f; Vector3 position = this.m_bezier.Position(t); if (propIndex != -1) { position.y = (float)data.m_extraData.GetUShort(currentPropIndex++) * 0.015625f; } position.y += prop.m_position.y; if (prop.m_position.x != 0f) { Vector3 vector3 = this.m_bezier.Tangent(t); if (reverse) { vector3 = -vector3; } vector3.y = 0f; vector3 = Vector3.Normalize(vector3); position.x += vector3.z * prop.m_position.x; position.z -= vector3.x * prop.m_position.x; } global::TreeInstance.RenderInstance(cameraInfo, variation2, position, scale2, brightness, RenderManager.DefaultColorLocation); } } } } } } } }
public static bool RenderPropsPrefix(BuildingAI __instance, RenderManager.CameraInfo cameraInfo, ushort buildingID, ref Building data, int layerMask, ref RenderManager.Instance instance, bool renderFixed, bool renderNonfixed, bool isActive) { if (__instance.m_info.m_props == null || ((layerMask & __instance.m_info.m_treeLayers) == 0 && !cameraInfo.CheckRenderDistance(instance.m_position, __instance.m_info.m_maxPropDistance + 72f))) { return(false); } int length = data.Length; Texture _HeightMap = null; Vector4 _HeightMapping = Vector4.zero; Vector4 _SurfaceMapping = Vector4.zero; Matrix4x4 lhs = Matrix4x4.zero; bool flag = false; DistrictManager instance2 = Singleton <DistrictManager> .instance; byte district = instance2.GetDistrict(data.m_position); Vector3 position = data.m_position; ushort num = Building.FindParentBuilding(buildingID); if (num != 0) { position = Singleton <BuildingManager> .instance.m_buildings.m_buffer[num].m_position; } byte park = instance2.GetPark(position); for (int i = 0; i < __instance.m_info.m_props.Length; i++) { BuildingInfo.Prop prop = __instance.m_info.m_props[i]; Randomizer r = new Randomizer((buildingID << 6) | prop.m_index); if (r.Int32(100u) >= prop.m_probability || length < prop.m_requiredLength) { continue; } PropInfo finalProp = prop.m_finalProp; TreeInfo finalTree = prop.m_finalTree; if (finalProp != null) { finalProp = finalProp.GetVariation(ref r, ref instance2.m_districts.m_buffer[district], park); float num2 = finalProp.m_minScale + (float)r.Int32(10000u) * (finalProp.m_maxScale - finalProp.m_minScale) * 0.0001f; Color color = finalProp.GetColor(ref r); if ((layerMask & (1 << finalProp.m_prefabDataLayer)) == 0 && !finalProp.m_hasEffects) { continue; } Vector4 dataVector = instance.m_dataVector3; Vector3 vector; if (prop.m_fixedHeight) { if (!renderFixed) { continue; } if (__instance.m_info.m_isFloating) { if (!flag) { Singleton <TerrainManager> .instance.HeightMap_sampleWaterHeightAndNormal(instance.m_position, 0.15f, out float h, out Vector3 normal); Vector3 position2 = instance.m_position; position2.y = h; Quaternion q = Quaternion.FromToRotation(Vector3.up, normal) * instance.m_rotation; lhs = Matrix4x4.TRS(position2, q, Vector3.one); flag = true; } Matrix4x4 rhs = default(Matrix4x4); rhs.SetTRS(prop.m_position, Quaternion.AngleAxis(prop.m_radAngle * 57.29578f, Vector3.down), new Vector3(num2, num2, num2)); rhs = lhs * rhs; vector = rhs.MultiplyPoint(Vector3.zero); if (cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance)) { InstanceID propRenderID = GetPropRenderIDReverse(__instance, buildingID, i, ref data); PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, rhs, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive); continue; } } else { vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (__instance.m_info.m_requireHeightMap) { vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } } } else { if (!renderNonfixed) { continue; } vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (!__instance.m_info.m_isFloating) { vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } if (!__instance.m_info.m_colorizeEverything || finalProp.m_isDecal) { dataVector.z = 0f; } } if (!cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance)) { continue; } InstanceID propRenderID2 = GetPropRenderIDReverse(__instance, buildingID, i, ref data); if (finalProp.m_requireWaterMap) { if (_HeightMap == null) { Singleton <TerrainManager> .instance.GetWaterMapping(data.m_position, out _HeightMap, out _HeightMapping, out _SurfaceMapping); } #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping); #endif } else if (finalProp.m_requireHeightMap) { #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2); #endif } else { #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, localData.m_angle + prop.m_radAngle, color, dataVector, isActive)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID2, vector, num2, data.m_angle + prop.m_radAngle, color, dataVector, isActive); #endif } } else { if (!(finalTree != null)) { continue; } finalTree = finalTree.GetVariation(ref r); float scale = finalTree.m_minScale + (float)r.Int32(10000u) * (finalTree.m_maxScale - finalTree.m_minScale) * 0.0001f; float brightness = finalTree.m_minBrightness + (float)r.Int32(10000u) * (finalTree.m_maxBrightness - finalTree.m_minBrightness) * 0.0001f; if ((layerMask & (1 << finalTree.m_prefabDataLayer)) != 0 && ((!prop.m_fixedHeight) ? renderNonfixed : renderFixed)) { Vector3 position3 = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (!prop.m_fixedHeight || __instance.m_info.m_requireHeightMap) { position3.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } Vector4 dataVector2 = instance.m_dataVector3; if (!__instance.m_info.m_colorizeEverything) { dataVector2.z = 0f; } #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => TreeInstance.RenderInstance(cameraInfo, finalTree, position3, scale, brightness, dataVector2)); #else TreeInstance.RenderInstance(cameraInfo, finalTree, position3, scale, brightness, dataVector2); #endif } } } return(false); }
public static bool RenderDestroyedPropsPrefix(BuildingAI __instance, RenderManager.CameraInfo cameraInfo, ushort buildingID, ref Building data, int layerMask, ref RenderManager.Instance instance, bool renderFixed, bool renderNonfixed) { if (__instance.m_info.m_props == null || !cameraInfo.CheckRenderDistance(instance.m_position, __instance.m_info.m_maxPropDistance + 72f)) { return(false); } int length = data.Length; Texture _HeightMap = null; Vector4 _HeightMapping = Vector4.zero; Vector4 _SurfaceMapping = Vector4.zero; BuildingProperties properties = Singleton <BuildingManager> .instance.m_properties; Building.Frame lastFrameData = data.GetLastFrameData(); float num = (float)Mathf.Max(0, lastFrameData.m_fireDamage - 127) * 0.0078125f; for (int i = 0; i < __instance.m_info.m_props.Length; i++) { BuildingInfo.Prop prop = __instance.m_info.m_props[i]; Randomizer r = new Randomizer((buildingID << 6) | prop.m_index); Randomizer r2 = new Randomizer((buildingID << 6) | prop.m_index); if (r.Int32(100u) >= prop.m_probability || length < prop.m_requiredLength) { continue; } PropInfo finalProp = prop.m_finalProp; if (!(finalProp != null)) { continue; } finalProp = finalProp.GetVariation(ref r); float scale = finalProp.m_minScale + (float)r.Int32(10000u) * (finalProp.m_maxScale - finalProp.m_minScale) * 0.0001f; Color color = finalProp.GetColor(ref r); if (!finalProp.m_isDecal) { finalProp = Singleton <PropManager> .instance.GetRandomPropInfo(ref r2, ItemClass.Service.Disaster); finalProp = finalProp.GetVariation(ref r2); scale = finalProp.m_minScale + (float)r2.Int32(10000u) * (finalProp.m_maxScale - finalProp.m_minScale) * 0.0001f; color = finalProp.GetColor(ref r2); if (properties != null && num != 0f) { color = Color.Lerp(color, properties.m_burnedColor, num); } } if ((layerMask & (1 << finalProp.m_prefabDataLayer)) == 0 && !finalProp.m_hasEffects) { continue; } Vector3 vector = instance.m_dataMatrix1.MultiplyPoint(prop.m_position); if (!prop.m_fixedHeight || __instance.m_info.m_requireHeightMap) { vector.y = (float)(int)instance.m_extraData.GetUShort(i) * 0.015625f; } if (!cameraInfo.CheckRenderDistance(vector, finalProp.m_maxRenderDistance) || !((!prop.m_fixedHeight) ? renderNonfixed : renderFixed)) { continue; } InstanceID propRenderID = GetPropRenderIDReverse(__instance, buildingID, 0, ref data); Vector4 dataVector = instance.m_dataVector3; if (!prop.m_fixedHeight && (!__instance.m_info.m_colorizeEverything || finalProp.m_isDecal)) { dataVector.z = 0f; } if (finalProp.m_requireWaterMap) { if (_HeightMap == null) { Singleton <TerrainManager> .instance.GetWaterMapping(data.m_position, out _HeightMap, out _HeightMapping, out _SurfaceMapping); } #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, vector, scale, localData.m_angle + prop.m_radAngle, color, dataVector, (localData.m_flags & Building.Flags.Active) != 0, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, vector, scale, data.m_angle + prop.m_radAngle, color, dataVector, (data.m_flags & Building.Flags.Active) != 0, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2, _HeightMap, _HeightMapping, _SurfaceMapping); #endif } else if (finalProp.m_requireHeightMap) { #if UseTask var localData = data; var localInstance = instance; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, vector, scale, localData.m_angle + prop.m_radAngle, color, dataVector, (localData.m_flags & Building.Flags.Active) != 0, localInstance.m_dataTexture0, localInstance.m_dataVector1, localInstance.m_dataVector2)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, vector, scale, data.m_angle + prop.m_radAngle, color, dataVector, (data.m_flags & Building.Flags.Active) != 0, instance.m_dataTexture0, instance.m_dataVector1, instance.m_dataVector2); #endif } else { #if UseTask var localData = data; Patcher.Dispatcher.Add(() => PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, vector, scale, localData.m_angle + prop.m_radAngle, color, dataVector, (localData.m_flags & Building.Flags.Active) != 0)); #else PropInstance.RenderInstance(cameraInfo, finalProp, propRenderID, vector, scale, data.m_angle + prop.m_radAngle, color, dataVector, (data.m_flags & Building.Flags.Active) != 0); #endif } } return(false); }
protected void CheckCollisions(ushort instanceID, ref CitizenInstance citizenData, Vector3 sourcePos, Vector3 targetPos, ushort buildingID, ref Vector3 pushAmount, ref float pushDivider) { Segment3 segment = new Segment3(sourcePos, targetPos); Vector3 min = segment.Min(); min.x -= this.m_info.m_radius; min.z -= this.m_info.m_radius; Vector3 max = segment.Max(); max.x += this.m_info.m_radius; max.y += this.m_info.m_height; max.z += this.m_info.m_radius; CitizenManager instance = Singleton <CitizenManager> .instance; int num = Mathf.Max((int)((min.x - 3f) / 8f + 1080f), 0); int num2 = Mathf.Max((int)((min.z - 3f) / 8f + 1080f), 0); int num3 = Mathf.Min((int)((max.x + 3f) / 8f + 1080f), 2159); int num4 = Mathf.Min((int)((max.z + 3f) / 8f + 1080f), 2159); for (int i = num2; i <= num4; i++) { for (int j = num; j <= num3; j++) { ushort num5 = instance.m_citizenGrid [i * 2160 + j]; int num6 = 0; while (num5 != 0) { num5 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num5, ref instance.m_instances.m_buffer [(int)num5], ref pushAmount, ref pushDivider); if (++num6 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } VehicleManager instance2 = Singleton <VehicleManager> .instance; int num7 = Mathf.Max((int)((min.x - 10f) / 32f + 270f), 0); int num8 = Mathf.Max((int)((min.z - 10f) / 32f + 270f), 0); int num9 = Mathf.Min((int)((max.x + 10f) / 32f + 270f), 539); int num10 = Mathf.Min((int)((max.z + 10f) / 32f + 270f), 539); for (int k = num8; k <= num10; k++) { for (int l = num7; l <= num9; l++) { ushort num11 = instance2.m_vehicleGrid [k * 540 + l]; int num12 = 0; while (num11 != 0) { num11 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num11, ref instance2.m_vehicles.m_buffer [(int)num11], ref pushAmount, ref pushDivider); if (++num12 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } for (int m = num8; m <= num10; m++) { for (int n = num7; n <= num9; n++) { ushort num13 = instance2.m_parkedGrid [m * 540 + n]; int num14 = 0; while (num13 != 0) { num13 = this.CheckCollisions(instanceID, ref citizenData, segment, min, max, num13, ref instance2.m_parkedVehicles.m_buffer [(int)num13], ref pushAmount, ref pushDivider); if (++num14 > 65536) { CODebugBase <LogChannel> .Error(LogChannel.Core, "Invalid list detected!\n" + Environment.StackTrace); break; } } } } if (buildingID != 0) { BuildingManager instance3 = Singleton <BuildingManager> .instance; BuildingInfo info = instance3.m_buildings.m_buffer [(int)buildingID].Info; if (info.m_props != null) { Vector3 position = instance3.m_buildings.m_buffer [(int)buildingID].m_position; float angle = instance3.m_buildings.m_buffer [(int)buildingID].m_angle; int length = instance3.m_buildings.m_buffer [(int)buildingID].Length; Matrix4x4 matrix4x = default(Matrix4x4); matrix4x.SetTRS(Building.CalculateMeshPosition(info, position, angle, length), Quaternion.AngleAxis(angle * 57.29578f, Vector3.down), Vector3.one); for (int num15 = 0; num15 < info.m_props.Length; num15++) { BuildingInfo.Prop prop = info.m_props [num15]; Randomizer randomizer = new Randomizer((int)buildingID << 6 | prop.m_index); if (randomizer.Int32(100u) < prop.m_probability && length >= prop.m_requiredLength) { Vector3 vector = matrix4x.MultiplyPoint(prop.m_position); if (vector.x >= min.x - 2f && vector.x <= max.x + 2f) { if (vector.z >= min.z - 2f && vector.z <= max.z + 2f) { PropInfo propInfo = prop.m_finalProp; TreeInfo treeInfo = prop.m_finalTree; float num16 = 0f; float num17 = 0f; if (propInfo != null) { propInfo = propInfo.GetVariation(ref randomizer); if (propInfo.m_isMarker || propInfo.m_isDecal || !propInfo.m_hasRenderer) { goto IL_7D3; } num16 = propInfo.m_generatedInfo.m_size.x * 0.5f; num17 = propInfo.m_generatedInfo.m_size.y; } else { if (treeInfo != null) { treeInfo = treeInfo.GetVariation(ref randomizer); num16 = (treeInfo.m_generatedInfo.m_size.x + treeInfo.m_generatedInfo.m_size.z) * 0.125f; num17 = treeInfo.m_generatedInfo.m_size.y; } } if (!prop.m_fixedHeight) { vector.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector); } else { if (info.m_requireHeightMap) { vector.y = Singleton <TerrainManager> .instance.SampleDetailHeight(vector) + prop.m_position.y; } } if (vector.y + num17 >= min.y && vector.y <= max.y) { num16 = this.m_info.m_radius + num16; float num19; float num18 = segment.DistanceSqr(vector, out num19); if (num18 < num16 * num16) { float num20 = num16 - Mathf.Sqrt(num18); float num21 = 1f - num18 / (num16 * num16); Vector3 a = segment.Position(num19 * 0.9f); a.y = 0f; vector.y = 0f; Vector3 vector2 = Vector3.Normalize(a - vector); Vector3 rhs = Vector3.Normalize(new Vector3(segment.b.x - segment.a.x, 0f, segment.b.z - segment.a.z)); Vector3 vector3 = new Vector3(rhs.z, 0f, -rhs.x) * Mathf.Abs(Vector3.Dot(vector2, rhs) * 0.5f); if (Vector3.Dot(vector2, vector3) >= 0f) { vector2 += vector3; } else { vector2 -= vector3; } pushAmount += vector2 * (num20 * num21); pushDivider += num21; } } } } } IL_7D3: ; } } } }