@@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
23
23
#include " mapgen_v5.h"
24
24
#include " mapgen_v6.h"
25
25
#include " mapgen_v7.h"
26
- #include " mapgen_fractal.h"
27
26
#include " cavegen.h"
28
27
29
28
NoiseParams nparams_caveliquids (0 , 1 , v3f(150.0 , 150.0 , 150.0 ), 776, 3, 0.6, 2.0);
@@ -32,17 +31,18 @@ NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0
32
31
// /////////////////////////////////////// Caves V5
33
32
34
33
35
- CaveV5::CaveV5 (MapgenV5 *mg, PseudoRandom *ps)
34
+ CaveV5::CaveV5 (Mapgen *mg, PseudoRandom *ps)
36
35
{
37
36
this ->mg = mg;
38
37
this ->vm = mg->vm ;
39
38
this ->ndef = mg->ndef ;
40
39
this ->water_level = mg->water_level ;
41
40
this ->ps = ps;
42
- this -> c_water_source = mg-> c_water_source ;
43
- this -> c_lava_source = mg-> c_lava_source ;
44
- this -> c_ice = mg-> c_ice ;
41
+ c_water_source = ndef-> getId ( " mapgen_water_source " ) ;
42
+ c_lava_source = ndef-> getId ( " mapgen_lava_source " ) ;
43
+ c_ice = ndef-> getId ( " mapgen_ice " ) ;
45
44
this ->np_caveliquids = &nparams_caveliquids;
45
+ this ->ystride = mg->csize .X ;
46
46
47
47
dswitchint = ps->range (1 , 14 );
48
48
flooded = ps->range (1 , 2 ) == 2 ;
@@ -150,7 +150,7 @@ void CaveV5::makeTunnel(bool dirswitch)
150
150
p = orpi + veci + of + rs / 2 ;
151
151
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
152
152
p.X >= node_min.X && p.X <= node_max.X ) {
153
- u32 index = (p.Z - node_min.Z ) * mg-> ystride + (p.X - node_min.X );
153
+ u32 index = (p.Z - node_min.Z ) * ystride + (p.X - node_min.X );
154
154
s16 h = mg->heightmap [index ];
155
155
if (h < p.Y )
156
156
return ;
@@ -161,7 +161,7 @@ void CaveV5::makeTunnel(bool dirswitch)
161
161
p = orpi + of + rs / 2 ;
162
162
if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
163
163
p.X >= node_min.X && p.X <= node_max.X ) {
164
- u32 index = (p.Z - node_min.Z ) * mg-> ystride + (p.X - node_min.X );
164
+ u32 index = (p.Z - node_min.Z ) * ystride + (p.X - node_min.X );
165
165
s16 h = mg->heightmap [index ];
166
166
if (h < p.Y )
167
167
return ;
@@ -215,7 +215,8 @@ void CaveV5::carveRoute(v3f vec, float f, bool randomize_xz)
215
215
216
216
float nval = NoisePerlin3D (np_caveliquids, startp.X ,
217
217
startp.Y , startp.Z , mg->seed );
218
- MapNode liquidnode = nval < 0.40 ? lavanode : waternode;
218
+ MapNode liquidnode = (nval < 0.40 && node_max.Y < MGV5_LAVA_DEPTH) ?
219
+ lavanode : waternode;
219
220
220
221
v3f fp = orp + vec * f;
221
222
fp.X += 0.1 * ps->range (-10 , 10 );
@@ -808,247 +809,3 @@ void CaveV7::carveRoute(v3f vec, float f, bool randomize_xz)
808
809
}
809
810
}
810
811
}
811
-
812
-
813
- // /////////////////////////////////////// Caves Fractal
814
-
815
-
816
- CaveFractal::CaveFractal (MapgenFractal *mg, PseudoRandom *ps)
817
- {
818
- this ->mg = mg;
819
- this ->vm = mg->vm ;
820
- this ->ndef = mg->ndef ;
821
- this ->water_level = mg->water_level ;
822
- this ->ps = ps;
823
- this ->c_water_source = mg->c_water_source ;
824
- this ->c_lava_source = mg->c_lava_source ;
825
- this ->c_ice = mg->c_ice ;
826
- this ->np_caveliquids = &nparams_caveliquids;
827
-
828
- dswitchint = ps->range (1 , 14 );
829
- flooded = ps->range (1 , 2 ) == 2 ;
830
-
831
- part_max_length_rs = ps->range (2 , 4 );
832
- tunnel_routepoints = ps->range (5 , ps->range (15 , 30 ));
833
- min_tunnel_diameter = 5 ;
834
- max_tunnel_diameter = ps->range (7 , ps->range (8 , 24 ));
835
-
836
- large_cave_is_flat = (ps->range (0 , 1 ) == 0 );
837
- }
838
-
839
-
840
- void CaveFractal::makeCave (v3s16 nmin, v3s16 nmax, int max_stone_height)
841
- {
842
- node_min = nmin;
843
- node_max = nmax;
844
- main_direction = v3f (0 , 0 , 0 );
845
-
846
- // Allowed route area size in nodes
847
- ar = node_max - node_min + v3s16 (1 , 1 , 1 );
848
- // Area starting point in nodes
849
- of = node_min;
850
-
851
- // Allow a bit more
852
- // (this should be more than the maximum radius of the tunnel)
853
- s16 insure = 10 ;
854
- s16 more = MYMAX (MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1 );
855
- ar += v3s16 (1 ,0 ,1 ) * more * 2 ;
856
- of -= v3s16 (1 ,0 ,1 ) * more;
857
-
858
- route_y_min = 0 ;
859
- // Allow half a diameter + 7 over stone surface
860
- route_y_max = -of.Y + max_stone_y + max_tunnel_diameter / 2 + 7 ;
861
-
862
- // Limit maximum to area
863
- route_y_max = rangelim (route_y_max, 0 , ar.Y - 1 );
864
-
865
- s16 min = 0 ;
866
- if (node_min.Y < water_level && node_max.Y > water_level) {
867
- min = water_level - max_tunnel_diameter/3 - of.Y ;
868
- route_y_max = water_level + max_tunnel_diameter/3 - of.Y ;
869
- }
870
- route_y_min = ps->range (min, min + max_tunnel_diameter);
871
- route_y_min = rangelim (route_y_min, 0 , route_y_max);
872
-
873
- s16 route_start_y_min = route_y_min;
874
- s16 route_start_y_max = route_y_max;
875
-
876
- route_start_y_min = rangelim (route_start_y_min, 0 , ar.Y - 1 );
877
- route_start_y_max = rangelim (route_start_y_max, route_start_y_min, ar.Y - 1 );
878
-
879
- // Randomize starting position
880
- orp = v3f (
881
- (float )(ps->next () % ar.X ) + 0.5 ,
882
- (float )(ps->range (route_start_y_min, route_start_y_max)) + 0.5 ,
883
- (float )(ps->next () % ar.Z ) + 0.5
884
- );
885
-
886
- // Add generation notify begin event
887
- v3s16 abs_pos (of.X + orp.X , of.Y + orp.Y , of.Z + orp.Z );
888
- GenNotifyType notifytype = GENNOTIFY_LARGECAVE_BEGIN;
889
- mg->gennotify .addEvent (notifytype, abs_pos);
890
-
891
- // Generate some tunnel starting from orp
892
- for (u16 j = 0 ; j < tunnel_routepoints; j++)
893
- makeTunnel (j % dswitchint == 0 );
894
-
895
- // Add generation notify end event
896
- abs_pos = v3s16 (of.X + orp.X , of.Y + orp.Y , of.Z + orp.Z );
897
- notifytype = GENNOTIFY_LARGECAVE_END;
898
- mg->gennotify .addEvent (notifytype, abs_pos);
899
- }
900
-
901
-
902
- void CaveFractal::makeTunnel (bool dirswitch)
903
- {
904
- // Randomize size
905
- s16 min_d = min_tunnel_diameter;
906
- s16 max_d = max_tunnel_diameter;
907
- rs = ps->range (min_d, max_d);
908
- s16 rs_part_max_length_rs = rs * part_max_length_rs;
909
-
910
- v3s16 maxlen;
911
- maxlen = v3s16 (
912
- rs_part_max_length_rs,
913
- rs_part_max_length_rs / 2 ,
914
- rs_part_max_length_rs
915
- );
916
-
917
- v3f vec;
918
- // Jump downward sometimes
919
- vec = v3f (
920
- (float )(ps->next () % maxlen.X ) - (float )maxlen.X / 2 ,
921
- (float )(ps->next () % maxlen.Y ) - (float )maxlen.Y / 2 ,
922
- (float )(ps->next () % maxlen.Z ) - (float )maxlen.Z / 2
923
- );
924
-
925
- // Do not make caves that are above ground.
926
- // It is only necessary to check the startpoint and endpoint.
927
- v3s16 orpi (orp.X , orp.Y , orp.Z );
928
- v3s16 veci (vec.X , vec.Y , vec.Z );
929
- v3s16 p;
930
-
931
- p = orpi + veci + of + rs / 2 ;
932
- if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
933
- p.X >= node_min.X && p.X <= node_max.X ) {
934
- u32 index = (p.Z - node_min.Z ) * mg->ystride + (p.X - node_min.X );
935
- s16 h = mg->heightmap [index ];
936
- if (h < p.Y )
937
- return ;
938
- } else if (p.Y > water_level) {
939
- return ; // If it's not in our heightmap, use a simple heuristic
940
- }
941
-
942
- p = orpi + of + rs / 2 ;
943
- if (p.Z >= node_min.Z && p.Z <= node_max.Z &&
944
- p.X >= node_min.X && p.X <= node_max.X ) {
945
- u32 index = (p.Z - node_min.Z ) * mg->ystride + (p.X - node_min.X );
946
- s16 h = mg->heightmap [index ];
947
- if (h < p.Y )
948
- return ;
949
- } else if (p.Y > water_level) {
950
- return ;
951
- }
952
-
953
- vec += main_direction;
954
-
955
- v3f rp = orp + vec;
956
- if (rp.X < 0 )
957
- rp.X = 0 ;
958
- else if (rp.X >= ar.X )
959
- rp.X = ar.X - 1 ;
960
-
961
- if (rp.Y < route_y_min)
962
- rp.Y = route_y_min;
963
- else if (rp.Y >= route_y_max)
964
- rp.Y = route_y_max - 1 ;
965
-
966
- if (rp.Z < 0 )
967
- rp.Z = 0 ;
968
- else if (rp.Z >= ar.Z )
969
- rp.Z = ar.Z - 1 ;
970
-
971
- vec = rp - orp;
972
-
973
- float veclen = vec.getLength ();
974
- if (veclen < 0.05 )
975
- veclen = 1.0 ;
976
-
977
- // Every second section is rough
978
- bool randomize_xz = (ps->range (1 , 2 ) == 1 );
979
-
980
- // Carve routes
981
- for (float f = 0 ; f < 1.0 ; f += 1.0 / veclen)
982
- carveRoute (vec, f, randomize_xz);
983
-
984
- orp = rp;
985
- }
986
-
987
-
988
- void CaveFractal::carveRoute (v3f vec, float f, bool randomize_xz)
989
- {
990
- MapNode airnode (CONTENT_AIR);
991
- MapNode waternode (c_water_source);
992
- MapNode lavanode (c_lava_source);
993
-
994
- v3s16 startp (orp.X , orp.Y , orp.Z );
995
- startp += of;
996
-
997
- float nval = NoisePerlin3D (np_caveliquids, startp.X ,
998
- startp.Y , startp.Z , mg->seed );
999
- MapNode liquidnode = (nval < 0.40 && node_max.Y < MGFRACTAL_LAVA_DEPTH) ?
1000
- lavanode : waternode;
1001
-
1002
- v3f fp = orp + vec * f;
1003
- fp.X += 0.1 * ps->range (-10 , 10 );
1004
- fp.Z += 0.1 * ps->range (-10 , 10 );
1005
- v3s16 cp (fp.X , fp.Y , fp.Z );
1006
-
1007
- s16 d0 = -rs/2 ;
1008
- s16 d1 = d0 + rs;
1009
- if (randomize_xz) {
1010
- d0 += ps->range (-1 , 1 );
1011
- d1 += ps->range (-1 , 1 );
1012
- }
1013
-
1014
- for (s16 z0 = d0; z0 <= d1; z0++) {
1015
- s16 si = rs / 2 - MYMAX (0 , abs (z0) - rs / 7 - 1 );
1016
- for (s16 x0 = -si - ps->range (0 ,1 ); x0 <= si - 1 + ps->range (0 ,1 ); x0++) {
1017
- s16 maxabsxz = MYMAX (abs (x0), abs (z0));
1018
-
1019
- s16 si2 = rs / 2 - MYMAX (0 , maxabsxz - rs / 7 - 1 );
1020
-
1021
- for (s16 y0 = -si2; y0 <= si2; y0 ++) {
1022
- if (large_cave_is_flat) {
1023
- // Make large caves not so tall
1024
- if (rs > 7 && abs (y0 ) >= rs / 3 )
1025
- continue ;
1026
- }
1027
-
1028
- v3s16 p (cp.X + x0, cp.Y + y0 , cp.Z + z0);
1029
- p += of;
1030
-
1031
- if (vm->m_area .contains (p) == false )
1032
- continue ;
1033
-
1034
- u32 i = vm->m_area .index (p);
1035
- content_t c = vm->m_data [i].getContent ();
1036
- if (!ndef->get (c).is_ground_content )
1037
- continue ;
1038
-
1039
- int full_ymin = node_min.Y - MAP_BLOCKSIZE;
1040
- int full_ymax = node_max.Y + MAP_BLOCKSIZE;
1041
-
1042
- if (flooded && full_ymin < water_level &&
1043
- full_ymax > water_level)
1044
- vm->m_data [i] = (p.Y <= water_level) ?
1045
- waternode : airnode;
1046
- else if (flooded && full_ymax < water_level)
1047
- vm->m_data [i] = (p.Y < startp.Y - 4 ) ?
1048
- liquidnode : airnode;
1049
- else
1050
- vm->m_data [i] = airnode;
1051
- }
1052
- }
1053
- }
1054
- }
0 commit comments