1
1
package net .glowstone .map ;
2
2
3
+ import static net .glowstone .map .GlowMapCanvas .MAP_SIZE ;
4
+
5
+ import net .glowstone .GlowServer ;
6
+ import net .glowstone .block .GlowBlock ;
7
+ import net .glowstone .block .MaterialValueManager .ValueCollection ;
8
+ import org .bukkit .Bukkit ;
9
+ import org .bukkit .Location ;
10
+ import org .bukkit .World ;
11
+ import org .bukkit .block .Block ;
3
12
import org .bukkit .entity .Player ;
4
13
import org .bukkit .map .MapCanvas ;
5
14
import org .bukkit .map .MapRenderer ;
10
19
*/
11
20
public final class GlowMapRenderer extends MapRenderer {
12
21
22
+ private static final int MAP_SIGHT_DISTANCE_SQUARED = 64 * 64 ;
13
23
private final GlowMapView map ;
14
24
15
25
public GlowMapRenderer (GlowMapView map ) {
@@ -19,7 +29,47 @@ public GlowMapRenderer(GlowMapView map) {
19
29
20
30
@ Override
21
31
public void render (MapView map , MapCanvas canvas , Player player ) {
22
- // todo
32
+ World world = map .getWorld ();
33
+ int scaleShift = map .getScale ().getValue ();
34
+ Location playerLoc = player .getLocation ();
35
+ int playerX = playerLoc .getBlockX ();
36
+ int playerZ = playerLoc .getBlockZ ();
37
+ int cornerX = map .getCenterX () - ((MAP_SIZE / 2 ) << scaleShift );
38
+ int cornerZ = map .getCenterZ () - ((MAP_SIZE / 2 ) << scaleShift );
39
+ for (int pixelX = 0 ; pixelX < MAP_SIZE ; pixelX ++) {
40
+ for (int pixelY = 0 ; pixelY < MAP_SIZE ; pixelY ++) {
41
+ int worldX = cornerX + (pixelX << scaleShift );
42
+ int worldZ = cornerZ + (pixelY << scaleShift );
43
+ if (((worldX - playerX ) * (worldX - playerX )
44
+ + (worldZ - playerZ ) * (worldZ - playerZ )) < MAP_SIGHT_DISTANCE_SQUARED ) {
45
+ // TODO: Should the highest block be skipped over if it's e.g. a flower or a
46
+ // technical block?
47
+ byte blockColor =
48
+ colorFor (world .getHighestBlockAt (worldX , worldZ ), worldX , worldZ );
49
+ canvas .setPixel (pixelX , pixelY , blockColor );
50
+ }
51
+ }
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Based on https://minecraft.gamepedia.com/Slime#.22Slime_chunks.22 but simplified (doesn't
57
+ * instantiate a Random, and doesn't vary with the world seed. Designed to be reproducible, so
58
+ * that updating a map doesn't change the color unless the map contents have changed.
59
+ */
60
+ private static byte pseudoRandomShade (int worldX , int worldZ ) {
61
+ return (byte ) ((
62
+ ((worldX * worldX * 0x4c1906 ) + (worldX * 0x5ac0db ) + ((worldZ * worldZ ) * 0x4307a7 )
63
+ + (worldZ * 0x5f24f ))) % 4 );
23
64
}
24
65
66
+ private static byte colorFor (Block block , int worldX , int worldZ ) {
67
+ // TODO: Some blocks vary in map color based on block states (e.g. wood species)
68
+ ValueCollection materialValues ;
69
+ materialValues = block instanceof GlowBlock ? ((GlowBlock ) block ).getMaterialValues ()
70
+ : ((GlowServer ) Bukkit .getServer ()).getMaterialValueManager ()
71
+ .getValues (block .getType ());
72
+ byte base_color = materialValues .getBaseMapColor ();
73
+ return (byte ) (base_color | pseudoRandomShade (worldX , worldZ ));
74
+ }
25
75
}
0 commit comments