1212import dan200 .computercraft .shared .util .WirelessHelpers ;
1313import net .minecraft .core .BlockPos ;
1414import net .minecraft .core .Vec3i ;
15+ import net .minecraft .world .level .block .Block ;
16+ import net .minecraft .world .level .chunk .LevelChunk ;
17+ import org .slf4j .Logger ;
18+ import org .slf4j .LoggerFactory ;
1519
1620import java .util .*;
1721import java .util .concurrent .ConcurrentHashMap ;
1822
1923public class WirelessNetwork implements PacketNetwork {
24+ private static final Logger log = LoggerFactory .getLogger (WirelessNetwork .class );
2025 private final Set <PacketReceiver > receivers = Collections .newSetFromMap (new ConcurrentHashMap <>());
2126
22- private final static List <Vec3i > obstructionBlocks = new ArrayList <Vec3i >(2048 );
27+ private final static ArrayList <Vec3i > obstructionBlocks = new ArrayList <Vec3i >(2048 );
28+ private final static ArrayList <BlockPos > unloadedBlocks = new ArrayList <BlockPos >(2048 );
2329
2430 @ Override
2531 public void addReceiver (PacketReceiver receiver ) {
@@ -50,11 +56,11 @@ private static void tryTransmit(PacketReceiver receiver, Packet packet, double r
5056 if (receiver .getLevel () == sender .getLevel ()) {
5157 var level = receiver .getLevel ();
5258 var receiveRange = Math .max (range , receiver .getRange ()); // Ensure range is symmetrical
53- var distanceSq = receiver .getPosition ().distanceToSqr (sender .getPosition ());
59+ var distance = receiver .getPosition ().distanceTo (sender .getPosition ());
5460
5561 // Interdimensional - just send it
5662 if (interdimensional && receiver .isInterdimensional ()) {
57- receiver .receiveSameDimension (packet , Math . sqrt ( distanceSq ) , 0.0 );
63+ receiver .receiveSameDimension (packet , distance , 0.0 );
5864 return ;
5965 }
6066
@@ -74,7 +80,7 @@ private static void tryTransmit(PacketReceiver receiver, Packet packet, double r
7480 useCache = false ;
7581 }
7682
77- if (distanceSq <= receiveRange * receiveRange ) {
83+ if (distance <= receiveRange ) {
7884 Vec3i senderBlockPosition = WirelessHelpers .floorToVec3i (sender .getPosition ());
7985 Vec3i receiverBlockPosition = WirelessHelpers .floorToVec3i (receiver .getPosition ());
8086
@@ -93,32 +99,89 @@ private static void tryTransmit(PacketReceiver receiver, Packet packet, double r
9399 if (cachedSignalDegradation > receiveRange ) {
94100 return ;
95101 }
96- receiver .receiveSameDimension (packet , Math . sqrt ( distanceSq ) , receiveRange - cachedSignalDegradation );
102+ receiver .receiveSameDimension (packet , distance , receiveRange - cachedSignalDegradation );
97103 return ;
98104 }
99105 }
100106
101107
102108 WirelessHelpers .Bresenham3D (obstructionBlocks , senderBlockPosition , receiverBlockPosition );
103- var signalDegradation = 0.0 ;
109+ var signalDegradation = distance ;
104110 var diagonalCompensation = WirelessHelpers .getDiagonalCompensation (senderBlockPosition , receiverBlockPosition );
105111
112+ var enumerationCounter = 0 ;
113+ var cancelled = false ;
114+
115+ unloadedBlocks .clear ();
116+
117+ var timer = System .currentTimeMillis (); // yes this is vulnerable to leap seconds, fight me
118+
106119 for (Vec3i blockVector : obstructionBlocks ) {
107- var explosionResistance = level .getBlockState (new BlockPos (blockVector ))
108- .getBlock ()
109- .getExplosionResistance ();
110- if (explosionResistance >= 100 )
111- explosionResistance /= 4 ;
112- signalDegradation += (signalDegradation / 100.0 * explosionResistance + 1.0 ) * diagonalCompensation ;
120+ var currentBlockPos = new BlockPos (blockVector );
121+ if (level .isLoaded (currentBlockPos ) && !level .isEmptyBlock (currentBlockPos )) {
122+ var currentBlockState = level .getBlockState (currentBlockPos );
123+ if (!currentBlockState .isAir ()) {
124+ var explosionResistance = currentBlockState .getBlock ().getExplosionResistance ();
125+ if (explosionResistance >= 100 )
126+ explosionResistance /= 4 ;
127+ signalDegradation += Math .sqrt (explosionResistance ) * 10.0 * diagonalCompensation ;
128+ }
129+ } else {
130+ unloadedBlocks .add (currentBlockPos );
131+ }
132+
133+ if (signalDegradation > receiveRange ) {
134+ break ;
135+ }
136+ enumerationCounter ++;
137+ if (timer + 500 <= System .currentTimeMillis ()) {
138+ log .warn ("Distance measure timeout in loaded blocks between [" + senderBlockPosition .getX () + ","
139+ + senderBlockPosition .getY () + ","
140+ + senderBlockPosition .getZ () + "] and ["
141+ + receiverBlockPosition .getX () + ","
142+ + receiverBlockPosition .getY () + ","
143+ + receiverBlockPosition .getZ () + "]"
144+ + " - blocks tested: " + enumerationCounter + "/" + obstructionBlocks .size ());
145+ cancelled = true ;
146+ break ;
147+ }
148+ }
149+
150+ for (BlockPos currentBlockPos : unloadedBlocks ) {
151+ var currentBlockState = level .getBlockState (currentBlockPos );
152+ if (!currentBlockState .isAir ()) {
153+ var explosionResistance = currentBlockState .getBlock ().getExplosionResistance ();
154+ if (explosionResistance >= 100 )
155+ explosionResistance /= 4 ;
156+ signalDegradation += Math .sqrt (explosionResistance ) * 10.0 * diagonalCompensation ;
157+ }
113158
114159 if (signalDegradation > receiveRange ) {
115160 break ;
116161 }
162+ enumerationCounter ++;
163+ if (timer + 500 <= System .currentTimeMillis ()) {
164+ log .warn ("Distance measure timeout in unloaded blocks between [" + senderBlockPosition .getX () + ","
165+ + senderBlockPosition .getY () + ","
166+ + senderBlockPosition .getZ () + "] and ["
167+ + receiverBlockPosition .getX () + ","
168+ + receiverBlockPosition .getY () + ","
169+ + receiverBlockPosition .getZ () + "]"
170+ + " - blocks tested: " + enumerationCounter + "/" + unloadedBlocks .size ());
171+ cancelled = true ;
172+ break ;
173+ }
174+ }
175+
176+ if (cancelled ) {
177+ // Extrapolating the signal degradation for the rest of the path
178+ signalDegradation = ((signalDegradation - distance ) / (double ) enumerationCounter / obstructionBlocks .size ()) + distance ;
179+ } else {
180+ ((WirelessModemPeripheral )sender ).addCachedSignalDegradation (receiverBlockPosition , signalDegradation );
117181 }
118182
119- ((WirelessModemPeripheral )sender ).addCachedSignalDegradation (receiverBlockPosition , signalDegradation );
120183 if (signalDegradation <= receiveRange ) {
121- receiver .receiveSameDimension (packet , Math . sqrt ( distanceSq ) , receiveRange - signalDegradation );
184+ receiver .receiveSameDimension (packet , distance , receiveRange - signalDegradation );
122185 }
123186 }
124187 } else {
0 commit comments