Skip to content

Commit f7a5a32

Browse files
authored
Overhaul zone generator (#20)
1 parent bb239d6 commit f7a5a32

File tree

269 files changed

+6325
-2029
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

269 files changed

+6325
-2029
lines changed
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
package brainwine.gameserver.util;
2+
3+
/**
4+
* K.jpg's OpenSimplex 2, faster variant
5+
* Source: {@linkplain https://github.com/KdotJPG/OpenSimplex2/blob/master/java/OpenSimplex2.java}
6+
*
7+
* Slightly modified - Removed unneeded parts, formatted code & added octave support.
8+
*/
9+
public class SimplexNoise {
10+
11+
private static float[] GRADIENTS_2D;
12+
private static final long PRIME_X = 0x5205402B9270C86FL;
13+
private static final long PRIME_Y = 0x598CD327003817B5L;
14+
private static final long HASH_MULTIPLIER = 0x53A3F72DEEC546F5L;
15+
private static final double SKEW_2D = 0.366025403784439;
16+
private static final double UNSKEW_2D = -0.21132486540518713;
17+
private static final int N_GRADS_2D_EXPONENT = 7;
18+
private static final int N_GRADS_2D = 1 << N_GRADS_2D_EXPONENT;
19+
private static final double NORMALIZER_2D = 0.01001634121365712;
20+
private static final float RSQUARED_2D = 0.5f;
21+
22+
static {
23+
GRADIENTS_2D = new float[N_GRADS_2D * 2];
24+
float[] grad2 = {
25+
0.38268343236509f, 0.923879532511287f,
26+
0.923879532511287f, 0.38268343236509f,
27+
0.923879532511287f, -0.38268343236509f,
28+
0.38268343236509f, -0.923879532511287f,
29+
-0.38268343236509f, -0.923879532511287f,
30+
-0.923879532511287f, -0.38268343236509f,
31+
-0.923879532511287f, 0.38268343236509f,
32+
-0.38268343236509f, 0.923879532511287f,
33+
0.130526192220052f, 0.99144486137381f,
34+
0.608761429008721f, 0.793353340291235f,
35+
0.793353340291235f, 0.608761429008721f,
36+
0.99144486137381f, 0.130526192220051f,
37+
0.99144486137381f, -0.130526192220051f,
38+
0.793353340291235f, -0.60876142900872f,
39+
0.608761429008721f, -0.793353340291235f,
40+
0.130526192220052f, -0.99144486137381f,
41+
-0.130526192220052f, -0.99144486137381f,
42+
-0.608761429008721f, -0.793353340291235f,
43+
-0.793353340291235f, -0.608761429008721f,
44+
-0.99144486137381f, -0.130526192220052f,
45+
-0.99144486137381f, 0.130526192220051f,
46+
-0.793353340291235f, 0.608761429008721f,
47+
-0.608761429008721f, 0.793353340291235f,
48+
-0.130526192220052f, 0.99144486137381f,
49+
};
50+
51+
for(int i = 0; i < grad2.length; i++) {
52+
grad2[i] = (float)(grad2[i] / NORMALIZER_2D);
53+
}
54+
55+
for(int i = 0, j = 0; i < GRADIENTS_2D.length; i++, j++) {
56+
if(j == grad2.length) {
57+
j = 0;
58+
}
59+
60+
GRADIENTS_2D[i] = grad2[j];
61+
}
62+
}
63+
64+
public static float noise1(long seed, double x) {
65+
return noise2(seed, x, 0);
66+
}
67+
68+
public static float noise1(long seed, double x, int octaves) {
69+
return noise2(seed, x, 0, octaves);
70+
}
71+
72+
public static float noise2(long seed, double x, double y) {
73+
return noise2(seed, x, y, 0);
74+
}
75+
76+
public static float noise2(long seed, double x, double y, int octaves) {
77+
// Get points for A2* lattice
78+
double s = SKEW_2D * (x + y);
79+
double xs = x + s, ys = y + s;
80+
return noise2_UnskewedBase(seed, xs, ys, octaves);
81+
}
82+
83+
private static float noise2_UnskewedBase(long seed, double xs, double ys, int octaves) {
84+
float noise = 0;
85+
double frequency;
86+
double amplitude;
87+
double xs1 = xs;
88+
double ys1 = ys;
89+
90+
for(int i = 0; i < octaves + 1; i++) {
91+
frequency = Math.pow(2, i);
92+
amplitude = Math.pow(0.5, i);
93+
xs = xs1 * frequency;
94+
ys = ys1 * frequency;
95+
96+
// Get base points and offsets.
97+
int xsb = fastFloor(xs), ysb = fastFloor(ys);
98+
float xi = (float)(xs - xsb), yi = (float)(ys - ysb);
99+
100+
// Prime pre-multiplication for hash.
101+
long xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y;
102+
103+
// Unskew.
104+
float t = (xi + yi) * (float)UNSKEW_2D;
105+
float dx0 = xi + t, dy0 = yi + t;
106+
107+
// First vertex.
108+
float value = 0;
109+
float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0;
110+
111+
if(a0 > 0) {
112+
value = (a0 * a0) * (a0 * a0) * grad(seed, xsbp, ysbp, dx0, dy0);
113+
}
114+
115+
// Second vertex.
116+
float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0);
117+
118+
if(a1 > 0) {
119+
float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D);
120+
float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D);
121+
value += (a1 * a1) * (a1 * a1) * grad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1);
122+
}
123+
124+
// Third vertex.
125+
if(dy0 > dx0) {
126+
float dx2 = dx0 - (float)UNSKEW_2D;
127+
float dy2 = dy0 - (float)(UNSKEW_2D + 1);
128+
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
129+
130+
if(a2 > 0) {
131+
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2);
132+
}
133+
}
134+
else {
135+
float dx2 = dx0 - (float)(UNSKEW_2D + 1);
136+
float dy2 = dy0 - (float)UNSKEW_2D;
137+
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2;
138+
139+
if(a2 > 0) {
140+
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp + PRIME_X, ysbp, dx2, dy2);
141+
}
142+
}
143+
144+
noise += value * amplitude;
145+
}
146+
147+
return noise;
148+
}
149+
150+
private static float grad(long seed, long xsvp, long ysvp, float dx, float dy) {
151+
long hash = seed ^ xsvp ^ ysvp;
152+
hash *= HASH_MULTIPLIER;
153+
hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1);
154+
int gi = (int)hash & ((N_GRADS_2D - 1) << 1);
155+
return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy;
156+
}
157+
158+
private static int fastFloor(double x) {
159+
int xi = (int)x;
160+
return x < xi ? xi - 1 : xi;
161+
}
162+
}

gameserver/src/main/java/brainwine/gameserver/zone/Zone.java

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
import brainwine.gameserver.server.models.BlockChangeData;
4848
import brainwine.gameserver.util.MapHelper;
4949
import brainwine.gameserver.util.MathUtils;
50+
import brainwine.gameserver.util.SimplexNoise;
5051
import brainwine.gameserver.util.Vector2i;
5152

5253
public class Zone {
@@ -132,7 +133,7 @@ public void tick(float deltaTime) {
132133
if(time >= 1.0F) {
133134
time -= 1.0F;
134135
}
135-
136+
136137
if(!getPlayers().isEmpty()) {
137138
if(now >= lastStatusUpdate + 4000) {
138139
sendMessage(new ZoneStatusMessage(getStatusConfig()));
@@ -429,6 +430,10 @@ public void placePrefab(Prefab prefab, int x, int y) {
429430
}
430431

431432
public void placePrefab(Prefab prefab, int x, int y, Random random) {
433+
placePrefab(prefab, x, y, random, random.nextLong()); // Can't get seed from random, so just generate one
434+
}
435+
436+
public void placePrefab(Prefab prefab, int x, int y, Random random, long seed) {
432437
int width = prefab.getWidth();
433438
int height = prefab.getHeight();
434439
Block[] blocks = prefab.getBlocks();
@@ -457,7 +462,12 @@ public void placePrefab(Prefab prefab, int x, int y, Random random) {
457462
});
458463

459464
for(int i = 0; i < width; i++) {
460-
for(int j = 0; j < height; j++) {
465+
for(int j = 0; j < height; j++) {
466+
// Skip ruined bits
467+
if(prefab.isRuin() && SimplexNoise.noise2(seed, (x + i) / 8.0, (y + j) / 8.0, 2) > 0.4) {
468+
continue;
469+
}
470+
461471
int index = j * width + (mirrored ? width - 1 - i : i);
462472
Block block = blocks[index];
463473
Item baseItem = replacedItems.getOrDefault(block.getBaseItem(), block.getBaseItem());
@@ -559,6 +569,7 @@ public void placePrefab(Prefab prefab, int x, int y, Random random) {
559569
}
560570
}
561571

572+
// Index dungeon if there are any guard blocks present
562573
if(guardBlocks > 0) {
563574
dungeons.put(dungeonId, guardBlocks);
564575
}

gameserver/src/main/java/brainwine/gameserver/zone/gen/DecorGenerator.java

Lines changed: 0 additions & 171 deletions
This file was deleted.

0 commit comments

Comments
 (0)