@@ -1066,6 +1066,91 @@ bool ServerEnvironment::swapNode(v3s16 p, const MapNode &n)
1066
1066
return true ;
1067
1067
}
1068
1068
1069
+ u8 ServerEnvironment::findSunlight (v3s16 pos) const
1070
+ {
1071
+ // Directions for neighbouring nodes with specified order
1072
+ static const v3s16 dirs[] = {
1073
+ v3s16 (-1 , 0 , 0 ), v3s16 (1 , 0 , 0 ), v3s16 (0 , 0 , -1 ), v3s16 (0 , 0 , 1 ),
1074
+ v3s16 (0 , -1 , 0 ), v3s16 (0 , 1 , 0 )
1075
+ };
1076
+
1077
+ const NodeDefManager *ndef = m_server->ndef ();
1078
+
1079
+ // found_light remembers the highest known sunlight value at pos
1080
+ u8 found_light = 0 ;
1081
+
1082
+ struct stack_entry {
1083
+ v3s16 pos;
1084
+ s16 dist;
1085
+ };
1086
+ std::stack<stack_entry> stack;
1087
+ stack.push ({pos, 0 });
1088
+
1089
+ std::unordered_map<s64, s8> dists;
1090
+ dists[MapDatabase::getBlockAsInteger (pos)] = 0 ;
1091
+
1092
+ while (!stack.empty ()) {
1093
+ struct stack_entry e = stack.top ();
1094
+ stack.pop ();
1095
+
1096
+ v3s16 currentPos = e.pos ;
1097
+ s8 dist = e.dist + 1 ;
1098
+
1099
+ for (const v3s16& off : dirs) {
1100
+ v3s16 neighborPos = currentPos + off;
1101
+ s64 neighborHash = MapDatabase::getBlockAsInteger (neighborPos);
1102
+
1103
+ // Do not walk neighborPos multiple times unless the distance to the start
1104
+ // position is shorter
1105
+ auto it = dists.find (neighborHash);
1106
+ if (it != dists.end () && dist >= it->second )
1107
+ continue ;
1108
+
1109
+ // Position to walk
1110
+ bool is_position_ok;
1111
+ MapNode node = m_map->getNode (neighborPos, &is_position_ok);
1112
+ if (!is_position_ok) {
1113
+ // This happens very rarely because the map at currentPos is loaded
1114
+ m_map->emergeBlock (neighborPos, false );
1115
+ node = m_map->getNode (neighborPos, &is_position_ok);
1116
+ if (!is_position_ok)
1117
+ continue ; // not generated
1118
+ }
1119
+
1120
+ const ContentFeatures &def = ndef->get (node);
1121
+ if (!def.sunlight_propagates ) {
1122
+ // Do not test propagation here again
1123
+ dists[neighborHash] = -1 ;
1124
+ continue ;
1125
+ }
1126
+
1127
+ // Sunlight could have come from here
1128
+ dists[neighborHash] = dist;
1129
+ u8 daylight = node.param1 & 0x0f ;
1130
+
1131
+ // In the special case where sunlight shines from above and thus
1132
+ // does not decrease with upwards distance, daylight is always
1133
+ // bigger than nightlight, which never reaches 15
1134
+ int possible_finlight = daylight - dist;
1135
+ if (possible_finlight <= found_light) {
1136
+ // Light from here cannot make a brighter light at currentPos than
1137
+ // found_light
1138
+ continue ;
1139
+ }
1140
+
1141
+ u8 nightlight = node.param1 >> 4 ;
1142
+ if (daylight > nightlight) {
1143
+ // Found a valid daylight
1144
+ found_light = possible_finlight;
1145
+ } else {
1146
+ // Sunlight may be darker, so walk the neighbours
1147
+ stack.push ({neighborPos, dist});
1148
+ }
1149
+ }
1150
+ }
1151
+ return found_light;
1152
+ }
1153
+
1069
1154
void ServerEnvironment::clearObjects (ClearObjectsMode mode)
1070
1155
{
1071
1156
infostream << " ServerEnvironment::clearObjects(): "
0 commit comments