ofs | hex dump | ascii |
---|
0000 | 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 00 00 04 00 00 00 04 00 08 06 00 00 00 7f 1d 2b | .PNG........IHDR...............+ |
0020 | 83 00 00 00 06 62 4b 47 44 00 ff 00 ff 00 ff a0 bd a7 93 00 00 00 09 70 48 59 73 00 00 0b 13 00 | .....bKGD..............pHYs..... |
0040 | 00 0b 13 01 00 9a 9c 18 00 00 00 07 74 49 4d 45 07 e0 09 08 0e 29 12 af 55 38 15 00 00 20 00 49 | ............tIME.....)..U8.....I |
0060 | 44 41 54 78 da ec dd 4f 8f 24 49 9f 27 74 37 f7 88 8c ae ec ce 87 62 6b f4 cc f4 88 59 0e 9c 11 | DATx...O.$I.'t7.......bk....Y... |
0080 | 20 ed 19 24 d8 11 2b 40 9c b9 70 02 ed 85 03 cc e1 39 3c e2 05 ec 61 91 f6 84 f6 c2 1f 69 b5 82 | ...$..+@..p......9<...a......i.. |
00a0 | 7d 11 33 5a c1 81 03 08 c1 c2 8e 04 07 d0 ae 40 53 3b ad 45 5b 3b f5 4c 54 c5 1f 77 e3 50 95 dd | }.3Z...........@S;.E[;.LT..w.P.. |
00c0 | 55 d9 11 19 df ac b2 aa cc 08 ff 7c a4 56 75 66 5a b8 bb 99 9b bb 5b 98 9b fd ac 7c f7 7b 7d ed | U..........|.VufZ.....[....|.{}. |
00e0 | 02 75 8a 92 75 65 51 a2 74 75 97 6d af 66 c9 ba 7e 99 ed 77 da 87 f9 e8 bb a6 ea 98 26 0c d3 95 | .u..ueQ.tu.m.f..~..w........&... |
0100 | ae 69 3e d2 72 2e a5 ed f6 5a 97 cb e2 59 76 80 e3 ae 36 dd 6f 5a ce d3 2e dc de 90 a5 1b 56 6d | .i>.r....Z...Yv...6.oZ........Vm |
0120 | eb fd b4 0f af b7 a1 75 bd 2a 4d cb a5 ee db de 5f d2 7a d0 5f 95 a6 d7 d1 34 86 f9 98 da 5e 6f | .......u.*M....._.z._....4....^o |
0140 | 69 7d 5e 7c 53 9a 1e 5f 5a 4f d3 ed c5 d7 ef 90 a6 4b cf 6f 78 bd 8d 61 45 88 1f 34 d9 7e fb 45 | i}^|S.._ZO.......K.ox..aE..4.~.E |
0160 | db fb e4 b0 6c bb bd f4 fc 0e 57 a5 fb ad fe 2f 76 5d d7 75 ff 64 ff b2 eb ba ae db 77 db 6e bf | ....l.....W..../v].u.d......w.n. |
0180 | be a7 ce 5e ff f4 ff c7 d2 fd ad bf f9 77 ba df fd dd df fd 78 5f c3 e1 4a b2 5e af b3 6b 65 b1 | ...^.........w......x_..J.^..ke. |
01a0 | 38 9c 87 23 db dd 6c 36 d1 76 57 ab 55 f7 57 fe bd 7f b5 db bf 39 9e 66 f9 6d 79 f0 3d 25 bd 47 | 8..#..l6.vW.U.W......9.f.my.=%.G |
01c0 | 9d be 76 ee df d0 b8 ad 77 ea d2 d7 69 53 34 6f 1b f5 9f 71 5c e9 6d 20 3c 96 db 76 c1 d4 f8 7a | ..v.....w...iS4o...q\.m.<..v...z |
01e0 | 7b ac f6 64 7a df ad 63 db 76 5d 5c 2e 8b b0 7d 10 de 77 a7 b1 6b 9b df f4 79 d9 3d ac 7e b5 fa | {..dz..c.v]\...}..w..k...y.=.~.. |
0200 | 9e 12 3f f7 c7 b6 f9 68 5d ff 4a 1f 3e f7 a7 d2 f6 bc a5 cf fd 3b cf e9 45 07 00 70 09 6a b9 bf | ..?....h].J.>........;..E..p.j.. |
0220 | 85 1f b6 99 ef 7e 01 bf be be 56 b6 00 5c 04 1d 00 00 00 f7 b8 ba ba 3a f8 fb ed 76 ab 70 00 38 | .....~....V..\.........:...v.p.8 |
0240 | 2b bd 22 00 00 00 80 cb 67 04 00 00 00 ed 55 45 00 f0 d4 18 01 00 00 00 00 33 60 04 00 00 00 0f | +.".....g.....UE.........3`..... |
0260 | 76 6a 65 9b 5e 2b 13 40 07 00 00 00 c7 83 0b a6 d6 eb 75 bc 6c 18 00 e8 00 00 00 ce d6 6a b5 ea | vje.^+.@..........u.l........j.. |
0280 | ba ae eb ca f8 7e 46 a3 39 e7 07 fc 54 28 c3 32 5c 8b 7c 7a 9c 35 c6 83 2c b4 91 ae 01 5e be c2 | .....~F.9...T(.2\.|z.5..,....^.. |
02a0 | f1 a5 eb cd 9b b4 0b 34 e2 76 02 00 00 00 33 b0 98 76 59 b7 65 19 c2 2d 86 bd a0 65 91 75 ab d6 | .......4.v....3..vY.e..-...e.u.. |
02c0 | 7d b6 c1 9a f6 56 a7 c7 37 84 c7 37 86 e5 17 76 b5 8c e1 92 c2 e9 bc ba 5a d3 ed 95 b6 e5 dc f8 | }....V..7..7...v........Z....... |
02e0 | ad 40 59 a4 e5 57 9b e6 37 ed 22 4b eb 69 7c 1d 95 b6 f9 4d df 62 a4 6f 87 d2 e3 eb c6 da f4 c6 | .@Y..W..7."K.i|....M.b.o........ |
0300 | 51 f7 e1 e6 c2 eb b7 4c b5 ed fd 20 dc 5e 3c 64 b7 f1 db a7 7e d9 76 7b fb 4d e3 fb 41 7a 59 36 | Q......L.....^<d....~.v{.M..AzY6 |
0320 | be ff d5 f4 7c 84 1b 9c c2 fc f6 e1 e8 ef b4 5e 95 be 34 bd 6f a4 e7 a3 a6 f9 4d af a3 d2 f8 b9 | ....|..........^..4.o.....M..... |
0340 | 0f 33 92 b6 eb 1f 7a 3f 8d 1b 12 63 db eb b2 8e 8f 73 9d f7 ab b6 df 03 c6 b7 8d db 89 8d db cf | .3....z?...c.....s.............. |
0360 | e9 73 3a 7e 7e b4 7d ac c6 f5 b4 74 6d 47 39 c5 f5 6f d7 f6 7c 94 3e 2d e7 b0 9e de 29 68 53 00 | .s:~~.}....tmG9..o..|.>-....)hS. |
0380 | 00 80 0b 51 4f 74 1a 64 5b b9 9d 5a 00 00 97 46 07 00 00 c0 3d b6 db ed 67 7d 7e 18 06 85 08 c0 | ...QOt.d[..Z...F....=...g}~..... |
03a0 | 93 20 06 00 00 00 00 cc 80 11 00 00 00 b4 77 62 7a 6a 6f 60 04 c0 57 67 04 00 00 00 00 cc 80 11 | ..............wbzjo`..Wg........ |
03c0 | 00 00 00 3c 58 1a 18 1e 00 1d 00 00 00 b3 36 8e 87 d7 a0 5c af d7 d1 e7 57 ab 55 bc cc 30 00 e8 | ...<X.........6....\....W.U..0.. |
03e0 | 00 00 00 ce d6 66 b3 e9 ba ae eb ea 54 15 46 20 5d c3 fb b1 3a 15 8e ad 09 9e 2e df 18 ef 67 0c | .....f......T.F.]...:.........g. |
0400 | 13 86 23 1c 4e 95 57 59 1c df 50 dd 87 eb 91 b7 3d 64 60 c6 f4 1b 03 00 00 c0 0c 2c d2 ae c2 b8 | ..#.N.WY..P.....=d`........,.... |
0420 | f7 b5 86 bd cb e1 d8 83 78 7e 59 d8 35 3a ed c3 ed 95 6c 83 fd 22 3b c0 3a 86 e5 32 b4 3e 1f 61 | ........x~Y.5:....l..";.:..2.>.a |
0440 | b2 34 bf cb 2c bf 53 ba e3 c6 e7 37 ce 6f fa b6 28 4c 36 ac b2 8c 8c 9b b6 fb 8d 8b 25 ac 2f 69 | .4..,.S....7.o..(L6.........%./i |
0460 | fd 6b 7d de e2 77 77 61 c2 3e 3d be c6 d7 6f fc 56 29 2d e6 f4 ed 53 78 5d d6 5d 7d 94 f3 91 d7 | .k}..wwa.>=...o.V)-...Sx].]}.... |
0480 | ab d2 b4 fe a5 e7 2d ed 0a cf af a3 f0 3e 19 9e 8f fe aa 6b 5a ff 4a e3 fc 4e 61 39 37 8f f8 ee | ......-......>.....kZ.J..Na97... |
04a0 | a5 3f 1c 6d 86 97 07 a6 6f 75 fd c6 ed ec d6 cf fd f0 39 98 3e 66 d2 fb 5a 97 b6 c7 1b 0f cd e8 | .?.m....ou........9.>f..Z....... |
04c0 | c3 e7 4c ad 4f fb b9 5f c2 13 52 fa b4 1d 56 9b d6 83 d6 cf fd 74 c4 4f 59 a5 ed d3 4f ab 2f a6 | ..L.O.._..R...V......t.OY...O./. |
04e0 | 00 00 00 17 e1 54 a3 33 ed fc b8 3b 07 ff e6 e6 46 e1 02 70 11 74 00 00 00 7c 82 ef be fb 2e 4a | .....T.3...;....F..p.t...|.....J |
0500 | b7 dd 6e 15 16 00 4f 82 18 00 00 00 00 30 03 46 00 00 00 d0 dc 74 6a be eb 9d 3f 97 41 99 01 7c | ..n...O......0.F.....tj...?.A..| |
0520 | 69 46 00 00 00 00 c0 0c 18 01 00 00 c0 83 4d 27 22 64 97 af fc 9a e9 d8 08 82 78 85 96 4f 5c e1 | iF............M'"d........x..O\. |
0540 | e6 d8 f6 7f 8a 20 fe d3 07 fa 45 58 46 69 94 f2 bb 51 f7 bd da 03 74 00 00 00 3c 3d e3 78 f8 9b | ..........EXFi...Q....t...<=.x.. |
0560 | e3 6a b5 8a 3e 3f 0c 43 be 5c 32 00 e8 00 00 00 ce d5 ed 1a d2 4f 6d ee f8 b1 a8 ff af 5f bf 8e | .j..>?.C.\2..........Om......_.. |
0580 | 3e 9f 76 00 6c 36 9b 93 eb 54 4f fb ae eb 97 ef fe ff f6 df 63 ea f8 b0 b5 c5 4f bd e1 3f b9 b5 | >.v.l6...TO.........c.....O..?.. |
05a0 | 72 bb df f7 ff 9e 5a 73 db db 6d 80 cf e6 56 0a 00 00 00 33 b0 28 8b b0 b7 77 ac 59 ba 2c 59 57 | r.....Zs..m...V....3.(...w.Y.,YW |
05c0 | 6a eb 31 6b d9 8e 4f f5 7e ff 78 7c e9 dc ab 29 db 6f 19 b2 0d 96 b0 9c bb a1 6d 3e d2 e3 9b 76 | j.1k..O.~.x|...).o........m>...v |
05e0 | b5 e5 e9 88 e7 07 9e 7c 2b f0 40 f1 7e c3 79 83 e3 a6 6d b9 c4 c2 72 e9 97 a5 ed f1 a5 d9 6d 9c | .......|+.@.~.y...m...r.......m. |
0600 | ae 94 c6 c7 37 d5 47 29 97 78 6e 67 78 7e a7 b0 fe f5 e9 7d a3 7f 9c fb 41 17 9e 8f 9f cd 79 3d | ....7.G).xngx~.....}....A.....y= |
0620 | 96 df ab d2 b6 9e 4e 8d 2b 42 5c 9f c3 e7 47 a9 6d ab 69 e3 7a da 0d 6d ef 43 a5 6f 7d 43 85 0b | ......N.+B\...G.m.i.z..m.C.o}C.. |
0640 | 50 1f 76 bd a5 d7 f9 14 b6 87 e2 fb 46 f3 b8 0c d9 fd 60 9a 1e 58 8e ad ee 7f ad 9f fb 63 e3 e7 | P.v.........F.....`..X.......c.. |
0660 | 7e eb 66 62 e3 84 d3 2e 7c cc ac 4a e3 f3 f6 48 cf fd b4 7d 1f 9e df f1 ed c7 c7 67 0a 00 00 70 | ~.fb....|..J...H...}.......g...p |
0680 | 21 5f 7e ca bd 0d b1 f4 4b 4c 3a 04 1f 00 ce 8d 0e 00 00 80 4f f0 ea d5 ab 83 bf 3f d6 81 d0 ba | !_~.....KL:.........O......?.... |
06a0 | 63 61 1c c7 d3 6f 8a a6 fc ed 59 1a 4b a1 b4 1e dd 15 b6 46 5b 8f 06 04 98 23 31 00 00 00 00 60 | ca...o....Y.K......F[....#1....` |
06c0 | 06 8c 00 00 00 e0 fc 7d 6e 58 88 70 84 41 1a 47 a8 2c 3f fd b3 e9 1c f9 bb a3 27 e2 b9 f5 c0 6c | .......}nX.p.A.G.,?.......'....l |
06e0 | 19 01 00 00 00 00 33 60 04 00 00 c0 57 30 0c ef 26 d9 6f 36 9b 76 db 3b 11 55 ba 0c 0f 88 c8 0d | ......3`....W0..&.o6.v.;.U...... |
0700 | c0 c5 33 02 00 00 00 00 66 c0 08 00 00 e0 2c ed 76 ef c3 db a7 8b 58 7f 25 b7 6f fa ef 1a c7 c7 | ..3.....f.....,.v.....X.%.o..... |
0720 | 99 a0 3d ed c3 e3 4e e7 b6 2f c2 b5 b6 77 d9 d0 83 e6 6b c2 03 70 94 11 00 00 00 00 30 03 8b 74 | ..=...N../...w....k..p......0..t |
0740 | 62 58 1c f1 b4 0f 7b 85 a7 b0 57 38 8d c8 5a ba a6 f9 88 23 c9 86 e9 a6 7d 58 ce 69 af fa d8 76 | bX....{...W8..Z....#....}X.i...v |
0760 | 7b 53 d8 4b 9f ae 25 3c 7c 93 9e b7 f0 c4 f5 b5 69 3d 18 77 6d eb 55 1f ae 9d 1c bf bd 48 eb 5f | {S.K..%<|.......i=.wm.U......H._ |
0780 | df b6 fe a5 fa 45 db fc a6 e5 97 be 25 1a 77 f5 71 ee 1b cd b7 17 de 0f f6 8d df b2 85 f7 e7 b8 | .....E......%.w.q............... |
07a0 | de a7 d9 0d ef 57 e3 36 bd 5f b5 ad f7 f1 1a e9 69 bd 0f 9f 97 53 e3 f3 5b 5a 5f bf cb d2 74 7b | .....W.6._......i....S..[Z_...t{ |
07c0 | 69 fb c0 2b 0c 38 fe 7c 4e ef 7f b5 f5 73 3a 6d e7 34 be 7e 5b b7 eb 9e fa 73 bf 0b bf 07 a4 a3 | i..+.8.|N....s:m.4.~[....s...... |
07e0 | 7f d2 e7 5b 7a de ca 23 d5 83 b8 de 87 8f 99 21 7c be d5 70 83 c3 2a 7c ee 87 ed 9c b4 de 0f 57 | ...[z..#.......!|..p..*|.......W |
0800 | e5 4e 07 00 00 c0 05 38 d5 79 90 36 c2 8f 0d e1 07 80 73 a7 03 00 00 e0 1e af 5e bd 3a f8 fb 9b | .N.....8.y.6......s.......^.:... |
0820 | 9b 9b 07 6d 67 bd 5e 7f f4 f3 8b 17 2f a2 cf 6d b7 db a3 7f eb 17 5d 37 1e ff f3 bb 91 35 bb 79 | ...mg.^...../..m......]7.....5.y |
0840 | 2c 03 30 9d 18 05 b3 f8 a6 ed a8 aa ae 7f f8 28 cb db 91 3a f1 08 d7 fe 81 e9 c4 49 00 74 00 00 | ,.0............(...:.......I.t.. |
0860 | 00 cc d7 ef ff a5 bf 3c 8b 7c fe e1 ff f2 87 4e 36 c0 09 66 d0 01 00 00 80 0e 00 00 00 00 40 07 | .......<.|.....N6..f..........@. |
0880 | 00 00 00 00 a0 03 00 00 00 00 78 1a 04 01 04 00 ce b3 11 b3 78 d7 8c a9 bb e9 49 1d 97 65 04 01 | ..........x.........x.....I..e.. |
08a0 | 78 aa 8c 00 00 00 00 80 19 58 a4 0b 86 96 be 86 e9 b2 1d 8f 9b 2c 5d 69 dd 89 9e 2e ed ba 08 d7 | x........X...........,]i........ |
08c0 | 76 4d d7 8a 4d 5f 4e 94 70 7b e1 3a af 75 ac 4d cb b9 84 f9 48 d7 b7 ed 86 c6 db eb d3 f3 1b 9e | vM..M_N.p{.:.u.M....H........... |
08e0 | b6 5d e3 e3 8b 17 e8 ad 4d eb 69 0d eb d5 98 e6 b7 f1 92 d2 25 5c 4b b9 84 c5 37 36 5e f3 ba 8e | .]......M.i.........%\K...76^... |
0900 | 61 3e c2 7a 55 c2 8c d4 da f6 fe 52 d3 f5 a4 c3 72 ee af c2 7c ec d2 eb ad 36 bd 8a e2 fa 17 de | a>.zU......R....r...|....6...... |
0920 | 87 fa a1 ed 9e c7 6d 6d 79 3b 78 b7 de 7b c3 e7 74 7a a1 f7 cb 6c 73 fb 75 eb e7 5b 67 1c 23 fc | ......mmy;x..{..tz...ls.u..[g.#. |
0940 | ec 82 2c ef af cb ec 7a 9b f6 ad db 61 e9 f3 bc 6d 3b 67 ff b6 ed fd 25 2d 97 f8 f9 91 b6 d7 c2 | ..,....z....a...m;g....%-....... |
0960 | 72 1e 1b 1f 5f 5c bd 96 6d 9f 83 75 d7 fa 7b 54 fa 3c 6f fc bd 22 6c 38 a5 cf fd b4 1e a4 f9 b8 | r..._\..m..u..{T.<o.."l8........ |
0980 | fb 9c f6 e8 04 00 66 21 ed dc 7a fd fa b5 c2 02 e0 22 e9 00 00 00 b8 c7 8b 17 2f 0e fe fe cd 9b | ......f!..z......"......../..... |
09a0 | 37 0f da ce cd cd cd 47 3f bf 7c f9 f2 93 3e f7 a1 e9 c4 9b a2 32 a3 c9 9e a7 46 f7 a5 a3 50 d2 | 7......G?.|...>......2....F...P. |
09c0 | d1 5c 43 3a ea eb d0 39 48 5f 58 a7 23 62 de d7 83 e2 72 05 4e dd 2b 15 01 00 00 00 5c 3e 23 00 | .\C:...9H_X.#b....r.N.+.....\>#. |
09e0 | 00 00 be 82 bb 53 0b be ff fe fb e8 73 db ed f6 e8 df fa be eb ee 0b 53 52 a7 f9 94 ef a9 79 db | .....S......s..........SR.....y. |
0a00 | 8b eb 70 1e f6 be ed 3c dd 43 e9 e2 58 3a e9 48 01 af f4 80 90 db 05 00 00 00 e8 00 00 00 00 00 | ..p....<.C..X:.H................ |
0a20 | 74 00 00 00 00 00 67 41 0c 00 00 e0 2c 95 f2 34 63 9e 9f db 32 82 7f ed af ff 8d b3 39 d6 5f ff | t.....gA....,..4c...2.......9._. |
0a40 | ea 0f 54 7c 80 cf 60 04 00 00 00 00 cc c0 22 ee 3c 0f a3 90 a6 51 4d fb 70 ec 41 1a 61 35 5d b3 | ..T|..`.......".<....QM.p.A.a5]. |
0a60 | 75 da 86 fb 1d c2 b5 62 87 30 a2 6c 58 30 75 0c f3 1b 76 dd 4c e1 f6 fa 21 4c b7 0c cb 6f 9f 9e | u......b.0.lX0u...v.L...!L...o.. |
0a80 | df b4 c2 84 f5 b4 71 b4 e3 e6 f5 b4 d4 a6 e7 37 ad 57 d3 be 6d 7e bb c6 d1 8b d3 85 8b eb 58 db | ......q........7.W..m~........X. |
0aa0 | 9e b7 b1 7b 14 e9 7d 32 ae 57 7d db 72 ee 1a 1f 5f 8d 37 d8 b8 be a4 d1 b3 1b 1f 5e eb 7c c4 f7 | ...{..}2.W}.r..._.7........^.|.. |
0ac0 | 83 31 bd bf 94 a6 e5 97 3e 67 4a e3 eb b2 37 86 11 0e b4 33 de fd 3b 86 cf fd d6 ab 07 a4 2b 28 | .1......>gJ...7....3..;.......+( |
0ae0 | f4 57 e1 7d 28 7c ce a4 ed d8 f8 f6 dc 3f ac bc 5b dd 27 d3 76 71 eb fb 5f bc 5a 48 5a 80 61 3e | .W.}(|.......?..[.'.vq.._.ZHZ.a> |
0b00 | 6a e3 ef 97 cd c7 84 b5 6e af 85 15 a6 84 df 43 e3 e7 ef ee 4e 07 80 5b 25 00 70 09 4e 35 c2 d2 | j.......n......C....N..[%.p.N5.. |
0b20 | ce d0 eb eb 6b 85 09 c0 45 d2 01 00 00 70 8f 71 3c fc 9a 65 bf df 2b 1c 00 ce 8a 18 00 00 00 00 | ....k...E....p.q<..e..+......... |
0b40 | 30 03 46 00 00 00 7c 05 37 37 37 1f fd fc f2 e5 cb 4f fa dc 87 a6 13 d3 1e ca 8c 5e f5 9c 9a 17 | 0.F...|.777......O.........^.... |
0b60 | bd 5f 87 71 32 c2 d6 f1 10 a6 3b 78 0e d2 39 cd 69 cc 93 c9 f5 05 84 f7 4a 45 00 00 00 00 3a 00 | ._.q2.....;x..9.i.......JE....:. |
0b80 | 00 00 00 00 1d 00 00 00 00 c0 39 10 03 00 00 38 4b 7d ff ee 3d 46 ba b6 32 00 cc fe d9 a9 08 00 | ..........9....8K}..=F..2....... |
0ba0 | 00 00 e0 f2 2d fe fb 3f 0d c3 86 d6 74 93 f5 49 67 b8 36 8e ba 1a 6f 30 d5 f8 25 46 1a 15 b6 75 | ....-..?....t..Ig.6...o0..%F...u |
0bc0 | 94 e0 b8 9c fb b6 d5 ea bf ba ce d2 fd d7 df 95 f0 f8 c2 74 25 3b c0 69 6a 5b 0f ea be 6d 39 a7 | ...................t%;.ij[...m9. |
0be0 | 6f d1 6a 98 df f4 bc d5 b1 3e 4a bd ea 97 a5 ed f1 8d e9 f9 0d 23 51 a7 f7 83 c6 63 b9 d2 7a 30 | o.j......>J..........#Q....c..z0 |
0c00 | 6e 6a cb ea 7c 32 82 f7 c3 ef 93 59 c2 29 3d bf bb b6 f9 1d ae c2 fa 97 de c7 87 f0 3e 94 e6 a3 | nj..|2.....Y.)=.............>... |
0c20 | 6f 7d 7c f1 83 b5 e9 7e 61 4e a6 6d 7d e0 8d 37 6c e7 b4 be 2e 6b db e7 7e 9a df be 6f db d0 4e | o}|....~aN.m}..7l....k..~...o..N |
0c40 | 9f 1f dd 94 de 77 db e6 37 be 8f 87 bb 8d 9f fb 69 3b 6c 08 ab 4b 98 ae f5 aa 19 f1 f3 32 ad 7f | .....w..7.......i;l..K.......2.. |
0c60 | 69 bb b3 66 e9 d2 95 48 ee b6 4f 4d 01 00 00 2e c2 a9 46 67 f9 b0 11 b9 53 5e 00 cc 8f 0e 00 00 | i..f...H..OM......Fg....S^...... |
0c80 | 80 7b 8c e3 e1 e1 3d d7 d7 87 87 9d ad d7 6b 85 06 c0 93 24 06 00 00 00 00 cc 80 11 00 00 00 5f | .{....=.......k....$..........._ |
0ca0 | c1 76 bb fd e8 e7 e7 cf 9f 7f f6 36 4f cd 3d 9d f6 f3 29 df 53 f3 7a d3 f9 b7 e9 8c e8 b8 6c cb | .v.........6O.=...).S.z.......l. |
0cc0 | e7 1c 4b 7a c8 ef 8f 59 6c 0c e0 04 23 00 00 00 00 40 07 00 00 00 00 a0 03 00 00 00 00 38 0b 62 | ..Kz...Yl...#....@...........8.b |
0ce0 | 00 00 00 67 e9 76 4e 7d bc 56 38 00 cc 9c 11 00 00 00 00 30 03 8b 7f 65 ab 10 e8 ba 6e bc 8c 6c | ...g.vN}.V8........0...e....n..l |
0d00 | fc ce 67 44 e4 3d a4 4e d9 6b a5 32 84 bb 0d a3 f3 d6 5d 98 2e 7c eb 95 1e 5f aa 1f b2 02 1c f7 | ..gD.=.N.k.2......]..|..._...... |
0d20 | 61 24 e5 30 bf 25 3c 6f 65 d1 38 ba 72 db c0 d1 cd f7 5b c2 82 a9 61 85 49 d3 a5 d1 a6 4b 3a d6 | a$.0.%<oe.8.r.....[...a.I....K:. |
0d40 | 2c ed 92 ae a5 6d f9 f5 e9 fd a0 6d 35 98 c2 eb 63 b8 0a cf ef 94 a5 eb 97 e1 f1 ed da 5e bf cb | ,....m.....m5...c............^.. |
0d60 | eb f0 84 f4 25 bf 1f 88 78 0e 1f 5f 8f e3 ed 73 3a bc ff a5 ed 88 74 d5 82 f0 be 36 86 f7 8d f4 | ....%...x.._...s:.....t....6.... |
0d80 | 86 9a de 27 f3 e7 79 db e7 60 dc ee 0c 77 db 2f d2 e7 42 6d 5a ce cd db 4d f1 f9 08 9f 0b e9 f3 | ...'..y..`...w./..BmZ...M....... |
0da0 | 3c 2c e8 7c 7b e1 d7 ad 6d 96 70 f1 2c 3d bf 61 7d 59 dd d9 be 5b 25 00 70 09 5a 75 76 ae d7 eb | <,.|{...m.p.,=.a}Y...[%.p.Zuv... |
0dc0 | 8f 7e be b9 b9 51 b8 00 5c 04 1d 00 00 00 f7 18 86 c3 3d 0b e3 38 2a 1c 00 ce 8a 18 00 00 00 00 | .~...Q..\.........=..8*......... |
0de0 | 30 03 46 00 00 00 7c 05 bf fc e5 2f 3f fa f9 87 1f 7e f8 ec 6d 9e 9a 7b 1a cf 01 be 84 46 ed 89 | 0.F...|..../?....~..m..{.....F.. |
0e00 | 79 b3 e3 9b 30 0e 4a ab c2 bf 67 83 65 99 ce 41 ce e6 02 4f 62 7a 01 21 23 00 00 00 00 40 07 00 | y...0.J...g.e..A...Obz.!#....@.. |
0e20 | 00 00 00 a0 03 00 00 00 00 38 0b 62 00 00 00 67 69 b9 5c 76 5d d7 75 65 57 9e d4 71 5d 5f 5f 3b | .........8.b...gi.\v].ueW..q]__; |
0e40 | 39 00 3c 49 46 00 00 00 00 c0 0c 18 01 c0 65 09 5f 02 d5 c6 4b 37 a7 81 80 4b 78 7c fd 32 4b 37 | 9.<IF.........e._...K7...Kx|.2K7 |
0e60 | 8d 8d cb 25 8c 16 5d 4a db b7 6d 65 48 8f 2f 3d bf b5 69 b9 b4 ae 7f 69 88 e9 69 9f d6 bf 6c 83 | ...%..]J..meH./=..i....i..i...l. |
0e80 | c3 b2 71 7d 1e da 6e af 86 f9 9d 76 d9 06 fb ab b6 d7 65 5c ed d3 74 61 7d de bf 4d a3 85 b7 ad | ..q}..n....v......e\..ta}..M.... |
0ea0 | 7f fd a2 6d 7e d3 f3 96 1e 5f ed bb ae 1b 3a e0 c0 7d b9 f9 4a 06 fb ec 42 7f ac fb 64 fc dc 6f | ...m~...._....:..}..J...B...d..o |
0ec0 | fd ea b3 6f 9d 8f 2c dd 18 e6 b7 2c da 1e 5f fa dc 8f ef e3 e1 7e c7 6d b8 c1 ab d6 17 54 e3 e6 | ...o..,....,.._......~.m.....T.. |
0ee0 | 64 98 70 bf 0e db 39 e9 f7 85 3b d7 af 0e 00 00 e0 32 be fc 94 72 6f cb 33 6d 5c 3f 7f fe 5c 61 | d.p...9...;......2...ro.3m\?..\a |
0f00 | 02 70 91 4c 01 00 00 00 00 1d 00 00 00 00 c0 25 30 05 00 00 e0 2b 78 f5 ea d5 47 3f ef f7 59 e0 | .p.L...........%0....+x...G?..Y. |
0f20 | 8b c5 e2 33 9a 6b d3 7c ca 77 dc dc 3f 6f 36 9d ee de 7a 7e 7a bf fc f9 06 d3 b9 cf f1 64 fe fa | ...3.k.|.w..?o6...z~z........d.. |
0f40 | c0 63 07 66 cb 08 00 00 00 00 d0 01 00 00 00 00 5c 02 53 00 00 00 3e b0 5e af 1f 94 fe fa fa fa | .c.f............\.S...>.^....... |
0f60 | 93 f6 b3 5a ad 3e eb 38 37 9b cd 03 d6 7b 03 00 1d 00 00 c0 99 da ed 76 ef ff af ed b7 e0 bb 5f | ...Z.>.87....{.........v......._ |
0f80 | cc 87 61 b8 b7 a3 e0 54 87 c1 b1 39 fc c7 b6 0b 00 5f 8a 29 00 00 00 00 30 03 46 00 70 51 4a d8 | ..a....T...9....._.)....0.F.pQJ. |
0fa0 | a5 55 c2 97 2e 65 cc d2 7d 9b 46 dd 4d 5f 52 ed db 6e 2f cd ef 14 ee b7 4c 6d df b6 d5 c6 51 aa | .U...e..}.F.M_R..n/.....Lm....Q. |
0fc0 | eb 36 ad 30 59 b2 be f5 4b ba d2 b6 ba a4 91 ad 4b 78 7e 0f 45 ac 3e 58 5f 76 d9 8e 4b fa a4 49 | .6.0Y...K.......Kx~.E.>X_v..K..I |
0fe0 | eb 41 b8 bd ba 6f 7b df 88 4f 6f 5a 5f fa ac 9c eb 98 95 f3 b4 09 77 9b 9e 8f fa 38 e5 97 de 87 | .A...o{..OoZ_.........w....8.... |
1000 | 5e 4f 5d d7 2d 3d f7 e0 90 bf f2 af ff 3b 51 ba 7f f3 5f fb b7 9b 3e 67 5a df 37 e2 e7 5b eb 76 | ^O].-=.......;Q..._...>gZ.7..[.v |
1020 | 58 f3 06 6a e3 76 ce d4 b6 9c bb c6 e5 d7 fa bc fd f1 ff f1 bf 45 e9 fe 8b ff e6 6f b6 3d 6d e1 | X..j.v...............E.....o.=m. |
1040 | f1 95 45 eb e5 37 b2 02 1c d3 e7 fe 95 0e 00 00 e0 02 d5 13 9d 93 1f 76 6e a5 1d 58 8f 61 b3 c9 | ..E..7.................vn..X.a.. |
1060 | 5a 75 ab d5 aa 79 07 0c 00 97 cd 63 03 00 00 00 74 00 00 00 00 00 97 c0 14 00 00 80 0b 35 a7 29 | Zu...y.....c....t............5.) |
1080 | 02 e5 44 5c 8d 52 b2 69 1f b5 f1 ec 90 f1 c0 74 93 38 b6 4c 38 09 f9 36 99 55 21 01 1d 00 00 00 | ..D\.R.i.......t.8.L8..6.U!..... |
10a0 | 0f 70 77 0e fe f5 f5 b5 42 01 40 07 00 00 c0 a5 bb ba ba 3a f8 fb ed 76 ab 70 00 38 2b 62 00 00 | .pw.....B.@........:...v.p.8+b.. |
10c0 | 00 00 c0 0c 18 01 00 00 9c a5 e5 72 f9 ee 7f 76 66 3e 03 40 c2 08 00 00 00 00 98 01 23 00 b8 2c | ...........r...vf>.@........#.., |
10e0 | 61 b4 dc 34 4c ee 3f b7 cb d2 fd b7 af b2 0d 7e 9b e6 23 7d 99 55 1a 6f af f5 e1 95 cb c8 6f 5e | a..4L.?........~..#}.U.o......o^ |
1100 | ff 1e 69 bf ad f3 1b 46 ca 8e f3 3b 5d ca fd a5 f5 79 ab 4f bb de 97 a7 5d 4f ff e5 5f 96 0e 38 | ..i....F...;]....y.O....]O.._..8 |
1120 | 6c b5 fc 26 4a f7 fc 17 ff ac c2 e2 c9 fb f6 fa bb c7 79 0e 86 ab 75 a4 ab ad 4c fb 30 1b 63 b8 | l..&J.............y...u...L.0.c. |
1140 | df f0 f8 ea 54 75 00 00 00 97 a7 9e 59 67 d3 b1 e0 82 a9 f5 7a dd 4d a3 f3 0e 40 ce 14 00 00 00 | ....Tu......Yg......z.M...@..... |
1160 | 00 98 01 23 00 00 80 59 d8 af 05 0b 3c e4 d7 bf fa 03 85 00 a0 03 00 00 80 73 d6 2f e7 13 2b 61 | ...#...Y....<............s./..+a |
1180 | da df df c1 53 fa ac 2c d2 f8 35 65 19 a6 3b 10 ef 63 dc 84 e7 6f 91 75 5a e9 da 02 74 00 00 00 | ....S..,..5e..;..c...o.uZ...t... |
11a0 | 7c 82 d5 6a a5 10 00 d0 01 00 00 30 37 db ed f6 b3 3e 3f 0c 83 42 04 e0 49 10 04 10 00 00 00 66 | |..j.......07....>?..B..I......f |
11c0 | c0 08 00 00 e0 2c 4d d3 fb 75 ff 4a 51 18 00 10 30 02 00 00 00 00 66 c0 08 00 2e 4a dd a7 71 70 | .....,M..u.JQ...0.....f./*
Minetest
Copyright (C) 2010-2020 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2015-2020 paramat
Copyright (C) 2010-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "util/numeric.h"
#include <cmath>
#include "map.h"
#include "mapgen.h"
#include "mapgen_v5.h"
#include "mapgen_v6.h"
#include "mapgen_v7.h"
#include "mg_biome.h"
#include "cavegen.h"
// TODO Remove this. Cave liquids are now defined and located using biome definitions
static NoiseParams nparams_caveliquids(0, 1, v3f(150.0, 150.0, 150.0), 776, 3, 0.6, 2.0);
////
//// CavesNoiseIntersection
////
CavesNoiseIntersection::CavesNoiseIntersection(
const NodeDefManager *nodedef, BiomeManager *biomemgr, v3s16 chunksize,
NoiseParams *np_cave1, NoiseParams *np_cave2, s32 seed, float cave_width)
{
assert(nodedef);
assert(biomemgr);
m_ndef = nodedef;
m_bmgr = biomemgr;
m_csize = chunksize;
m_cave_width = cave_width;
m_ystride = m_csize.X;
m_zstride_1d = m_csize.X * (m_csize.Y + 1);
// Noises are created using 1-down overgeneration
// A Nx-by-1-by-Nz-sized plane is at the bottom of the desired for
// re-carving the solid overtop placed for blocking sunlight
noise_cave1 = new Noise(np_cave1, seed, m_csize.X, m_csize.Y + 1, m_csize.Z);
noise_cave2 = new Noise(np_cave2, seed, m_csize.X, m_csize.Y + 1, m_csize.Z);
}
CavesNoiseIntersection::~CavesNoiseIntersection()
{
delete noise_cave1;
delete noise_cave2;
}
void CavesNoiseIntersection::generateCaves(MMVManip *vm,
v3s16 nmin, v3s16 nmax, biome_t *biomemap)
{
assert(vm);
assert(biomemap);
noise_cave1->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z);
noise_cave2->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z);
const v3s16 &em = vm->m_area.getExtent();
u32 index2d = 0; // Biomemap index
for (s16 z = nmin.Z; z <= nmax.Z; z++)
for (s16 x = nmin.X; x <= nmax.X; x++, index2d++) {
bool column_is_open = false; // Is column open to overground
bool is_under_river = false; // Is column under river water
bool is_under_tunnel = false; // Is tunnel or is under tunnel
bool is_top_filler_above = false; // Is top or filler above node
// Indexes at column top
u32 vi = vm->m_area.index(x, nmax.Y, z);
u32 index3d = (z - nmin.Z) * m_zstride_1d + m_csize.Y * m_ystride +
(x - nmin.X); // 3D noise index
// Biome of column
Biome *biome = (Biome *)m_bmgr->getRaw(biomemap[index2d]);
u16 depth_top = biome->depth_top;
u16 base_filler = depth_top + biome->depth_filler;
u16 depth_riverbed = biome->depth_riverbed;
u16 nplaced = 0;
// Don't excavate the overgenerated stone at nmax.Y + 1,
// this creates a 'roof' over the tunnel, preventing light in
// tunnels at mapchunk borders when generating mapchunks upwards.
// This 'roof' is removed when the mapchunk above is generated.
for (s16 y = nmax.Y; y >= nmin.Y - 1; y--,
index3d -= m_ystride,
VoxelArea::add_y(em, vi, -1)) {
content_t c = vm->m_data[vi].getContent();
if (c == CONTENT_AIR || c == biome->c_water_top ||
c == biome->c_water) {
column_is_open = true;
is_top_filler_above = false;
continue;
}
if (c == biome->c_river_water) {
column_is_open = true;
is_under_river = true;
is_top_filler_above = false;
continue;
}
// Ground
float d1 = contour(noise_cave1->result[index3d]);
float d2 = contour(noise_cave2->result[index3d]);
if (d1 * d2 > m_cave_width && m_ndef->get(c).is_ground_content) {
// In tunnel and ground content, excavate
vm->m_data[vi] = MapNode(CONTENT_AIR);
is_under_tunnel = true;
// If tunnel roof is top or filler, replace with stone
if (is_top_filler_above)
vm->m_data[vi + em.X] = MapNode(biome->c_stone);
is_top_filler_above = false;
} else if (column_is_open && is_under_tunnel &&
(c == biome->c_stone || c == biome->c_filler)) {
// Tunnel entrance floor, place biome surface nodes
if (is_under_river) {
if (nplaced < depth_riverbed) {
vm->m_data[vi] = MapNode(biome->c_riverbed);
is_top_filler_above = true;
nplaced++;
} else {
// Disable top/filler placement
column_is_open = false;
is_under_river = false;
is_under_tunnel = false;
}
} else if (nplaced < depth_top) {
vm->m_data[vi] = MapNode(biome->c_top);
is_top_filler_above = true;
nplaced++;
} else if (nplaced < base_filler) {
vm->m_data[vi] = MapNode(biome->c_filler);
is_top_filler_above = true;
nplaced++;
} else {
// Disable top/filler placement
column_is_open = false;
is_under_tunnel = false;
}
} else {
// Not tunnel or tunnel entrance floor
// Check node for possible replacing with stone for tunnel roof
if (c == biome->c_top || c == biome->c_filler)
is_top_filler_above = true;
column_is_open = false;
}
}
}
}
////
//// CavernsNoise
////
CavernsNoise::CavernsNoise(
const NodeDefManager *nodedef, v3s16 chunksize, NoiseParams *np_cavern,
s32 seed, float cavern_limit, float cavern_taper, float cavern_threshold)
{
assert(nodedef);
m_ndef = nodedef;
m_csize = chunksize;
m_cavern_limit = cavern_limit;
m_cavern_taper = cavern_taper;
m_cavern_threshold = cavern_threshold;
m_ystride = m_csize.X;
m_zstride_1d = m_csize.X * (m_csize.Y + 1);
// Noise is created using 1-down overgeneration
// A Nx-by-1-by-Nz-sized plane is at the bottom of the desired for
// re-carving the solid overtop placed for blocking sunlight
noise_cavern = new Noise(np_cavern, seed, m_csize.X, m_csize.Y + 1, m_csize.Z);
c_water_source = m_ndef->getId("mapgen_water_source");
if (c_water_source == CONTENT_IGNORE)
c_water_source = CONTENT_AIR;
c_lava_source = m_ndef->getId("mapgen_lava_source");
if (c_lava_source == CONTENT_IGNORE)
c_lava_source = CONTENT_AIR;
}
CavernsNoise::~CavernsNoise()
{
delete noise_cavern;
}
bool CavernsNoise::generateCaverns(MMVManip *vm, v3s16 nmin, v3s16 nmax)
{
assert(vm);
// Calculate noise
noise_cavern->perlinMap3D(nmin.X, nmin.Y - 1, nmin.Z);
// Cache cavern_amp values
float *cavern_amp = new float[m_csize.Y + 1];
u8 cavern_amp_index = 0; // Index zero at column top
for (s16 y = nmax.Y; y >= nmin.Y - 1; y--, cavern_amp_index++) {
cavern_amp[cavern_amp_index] =
MYMIN((m_cavern_limit - y) / (float)m_cavern_taper, 1.0f);
}
//// Place nodes
bool near_cavern = false;
const v3s16 &em = vm->m_area.getExtent();
u32 index2d = 0;
for (s16 z = nmin.Z; z <= nmax.Z; z++)
for (s16 x = nmin.X; x <= nmax.X; x++, index2d++) {
// Reset cave_amp index to column top
cavern_amp_index = 0;
// Initial voxelmanip index at column top
u32 vi = vm->m_area.index(x, nmax.Y, z);
// Initial 3D noise index at column top
u32 index3d = (z - nmin.Z) * m_zstride_1d + m_csize.Y * m_ystride +
(x - nmin.X);
// Don't excavate the overgenerated stone at node_max.Y + 1,
// this creates a 'roof' over the cavern, preventing light in
// caverns at mapchunk borders when generating mapchunks upwards.
// This 'roof' is excavated when the mapchunk above is generated.
for (s16 y = nmax.Y; y >= nmin.Y - 1; y--,
index3d -= m_ystride,
VoxelArea::add_y(em, vi, -1),
cavern_amp_index++) {
content_t c = vm->m_data[vi].getContent();
float n_absamp_cavern = std::fabs(noise_cavern->result[index3d]) *
cavern_amp[cavern_amp_index];
// Disable CavesRandomWalk at a safe distance from caverns
// to avoid excessively spreading liquids in caverns.
if (n_absamp_cavern > m_cavern_threshold - 0.1f) {
near_cavern = true;
if (n_absamp_cavern > m_cavern_threshold &&
m_ndef->get(c).is_ground_content)
vm->m_data[vi] = MapNode(CONTENT_AIR);
}
}
}
delete[] cavern_amp;
return near_cavern;
}
////
//// CavesRandomWalk
////
CavesRandomWalk::CavesRandomWalk(
const NodeDefManager *ndef,
GenerateNotifier *gennotify,
s32 seed,
int water_level,
content_t water_source,
content_t lava_source,
float large_cave_flooded,
BiomeGen *biomegen)
{
assert(ndef);
this->ndef = ndef;
this->gennotify = gennotify;
this->seed = seed;
this->water_level = water_level;
this->np_caveliquids = &nparams_caveliquids;
this->large_cave_flooded = large_cave_flooded;
this->bmgn = biomegen;
c_water_source = water_source;
if (c_water_source == CONTENT_IGNORE)
c_water_source = ndef->getId("mapgen_water_source");
if (c_water_source == CONTENT_IGNORE)
c_water_source = CONTENT_AIR;
c_lava_source = lava_source;
if (c_lava_source == CONTENT_IGNORE)
c_lava_source = ndef->getId("mapgen_lava_source");
if (c_lava_source == CONTENT_IGNORE)
c_lava_source = CONTENT_AIR;
}
void CavesRandomWalk::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax,
PseudoRandom *ps, bool is_large_cave, int max_stone_height, s16 *heightmap)
{
assert(vm);
assert(ps);
this->vm = vm;
this->ps = ps;
this->node_min = nmin;
this->node_max = nmax;
this->heightmap = heightmap;
this->large_cave = is_large_cave;
this->ystride = nmax.X - nmin.X + 1;
flooded = ps->range(1, 1000) <= large_cave_flooded * 1000.0f;
// If flooded:
// Get biome at mapchunk midpoint. If cave liquid defined for biome, use it.
// If defined liquid is "air", disable 'flooded' to avoid placing "air".
use_biome_liquid = false;
if (flooded && bmgn) {
v3s16 midp = node_min + (node_max - node_min) / v3s16(2, 2, 2);
Biome *biome = (Biome *)bmgn->getBiomeAtPoint(midp);
if (biome->c_cave_liquid[0] != CONTENT_IGNORE) {
use_biome_liquid = true;
c_biome_liquid =
biome->c_cave_liquid[ps->range(0, biome->c_cave_liquid.size() - 1)];
if (c_biome_liquid == CONTENT_AIR)
flooded = false;
}
}
// Set initial parameters from randomness
int dswitchint = ps->range(1, 14);
if (large_cave) {
part_max_length_rs = ps->range(2, 4);
tunnel_routepoints = ps->range(5, ps->range(15, 30));
min_tunnel_diameter = 5;
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
} else {
part_max_length_rs = ps->range(2, 9);
tunnel_routepoints = ps->range(10, ps->range(15, 30));
min_tunnel_diameter = 2;
max_tunnel_diameter = ps->range(2, 6);
}
large_cave_is_flat = (ps->range(0, 1) == 0);
main_direction = v3f(0, 0, 0);
// Allowed route area size in nodes
ar = node_max - node_min + v3s16(1, 1, 1);
// Area starting point in nodes
of = node_min;
// Allow caves to extend up to 16 nodes beyond the mapchunk edge, to allow
// connecting with caves of neighbor mapchunks.
// 'insure' is needed to avoid many 'out of voxelmanip' cave nodes.
const s16 insure = 2;
s16 more = MYMAX(MAP_BLOCKSIZE - max_tunnel_diameter / 2 - insure, 1);
ar += v3s16(1, 1, 1) * more * 2;
of -= v3s16(1, 1, 1) * more;
route_y_min = 0;
// Allow half a diameter + 7 over stone surface
route_y_max = -of.Y + max_stone_height + max_tunnel_diameter / 2 + 7;
// Limit maximum to area
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
if (large_cave) {
s16 minpos = 0;
if (node_min.Y < water_level && node_max.Y > water_level) {
minpos = water_level - max_tunnel_diameter / 3 - of.Y;
route_y_max = water_level + max_tunnel_diameter / 3 - of.Y;
}
route_y_min = ps->range(minpos, minpos + max_tunnel_diameter);
route_y_min = rangelim(route_y_min, 0, route_y_max);
}
s16 route_start_y_min = route_y_min;
s16 route_start_y_max = route_y_max;
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1);
route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1);
// Randomize starting position
orp.Z = (float)(ps->next() % ar.Z) + 0.5f;
orp.Y = (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5f;
orp.X = (float)(ps->next() % ar.X) + 0.5f;
// Add generation notify begin event
if (gennotify) {
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
gennotify->addEvent(notifytype, abs_pos);
}
// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);
// Add generation notify end event
if (gennotify) {
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
gennotify->addEvent(notifytype, abs_pos);
}
}
void CavesRandomWalk::makeTunnel(bool dirswitch)
{
if (dirswitch && !large_cave) {
main_direction.Z = ((float)(ps->next() % 20) - (float)10) / 10;
main_direction.Y = ((float)(ps->next() % 20) - (float)10) / 30;
main_direction.X = ((float)(ps->next() % 20) - (float)10) / 10;
main_direction *= (float)ps->range(0, 10) / 10;
}
// Randomize size
s16 min_d = min_tunnel_diameter;
s16 max_d = max_tunnel_diameter;
rs = ps->range(min_d, max_d);
s16 rs_part_max_length_rs = rs * part_max_length_rs;
v3s16 maxlen;
if (large_cave) {
maxlen = v3s16(
rs_part_max_length_rs,
rs_part_max_length_rs / 2,
rs_part_max_length_rs
);
} else {
maxlen = v3s16(
rs_part_max_length_rs,
ps->range(1, rs_part_max_length_rs),
rs_part_max_length_rs
);
}
v3f vec;
// Jump downward sometimes
if (!large_cave && ps->range(0, 12) == 0) {
vec.Z = (float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2;
vec.Y = (float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y;
vec.X = (float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2;
} else {
vec.Z = (float)(ps->next() % (maxlen.Z * 1)) - (float)maxlen.Z / 2;
vec.Y = (float)(ps->next() % (maxlen.Y * 1)) - (float)maxlen.Y / 2;
vec.X = (float)(ps->next() % (maxlen.X * 1)) - (float)maxlen.X / 2;
}
// Do not make caves that are above ground.
// It is only necessary to check the startpoint and endpoint.
v3s16 p1 = v3s16(orp.X, orp.Y, orp.Z) + of + rs / 2;
v3s16 p2 = v3s16(vec.X, vec.Y, vec.Z) + p1;
if (isPosAboveSurface(p1) || isPosAboveSurface(p2))
return;
vec += main_direction;
v3f rp = orp + vec;
if (rp.X < 0)
rp.X = 0;
else if (rp.X >= ar.X)
rp.X = ar.X - 1;
if (rp.Y < route_y_min)
rp.Y = route_y_min;
else if (rp.Y >= route_y_max)
rp.Y = route_y_max - 1;
if (rp.Z < 0)
rp.Z = 0;
else if (rp.Z >= ar.Z)
rp.Z = ar.Z - 1;
vec = rp - orp;
float veclen = vec.getLength();
if (veclen < 0.05f)
veclen = 1.0f;
// Every second section is rough
bool randomize_xz = (ps->range(1, 2) == 1);
// Carve routes
for (float f = 0.f; f < 1.0f; f += 1.0f / veclen)
carveRoute(vec, f, randomize_xz);
orp = rp;
}
void CavesRandomWalk::carveRoute(v3f vec, float f, bool randomize_xz)
{
MapNode airnode(CONTENT_AIR);
MapNode waternode(c_water_source);
MapNode lavanode(c_lava_source);
v3s16 startp(orp.X, orp.Y, orp.Z);
startp += of;
v3f fp = orp + vec * f;
fp.X += 0.1f * ps->range(-10, 10);
fp.Z += 0.1f * ps->range(-10, 10);
v3s16 cp(fp.X, fp.Y, fp.Z);
// Choose cave liquid
MapNode liquidnode = CONTENT_IGNORE;
if (flooded) {
if (use_biome_liquid) {
liquidnode = c_biome_liquid;
} else {
// If cave liquid not defined by biome, fallback to old hardcoded behaviour.
// TODO 'np_caveliquids' is deprecated and should eventually be removed.
// Cave liquids are now defined and located using biome definitions.
float nval = NoisePerlin3D(np_caveliquids, startp.X,
startp.Y, startp.Z, seed);
liquidnode = (nval < 0.40f && node_max.Y < water_level - 256) ?
lavanode : waternode;
}
}
s16 d0 = -rs / 2;
s16 d1 = d0 + rs;
if (randomize_xz) {
d0 += ps->range(-1, 1);
d1 += ps->range(-1, 1);
}
bool flat_cave_floor = !large_cave && ps->range(0, 2) == 2;
for (s16 z0 = d0; z0 <= d1; z0++) {
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
for (s16 y0 = -si2; y0 <= si2; y0++) {
// Make better floors in small caves
if (flat_cave_floor && y0 <= -rs / 2 && rs <= 7)
continue;
if (large_cave_is_flat) {
// Make large caves not so tall
if (rs > 7 && abs(y0) >= rs / 3)
continue;
}
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
p += of;
if (!vm->m_area.contains(p))
continue;
u32 i = vm->m_area.index(p);
content_t c = vm->m_data[i].getContent();
if (!ndef->get(c).is_ground_content)
continue;
if (large_cave) {
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
if (flooded && full_ymin < water_level && full_ymax > water_level)
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
else if (flooded && full_ymax < water_level)
vm->m_data[i] = (p.Y < startp.Y - 4) ? liquidnode : airnode;
else
vm->m_data[i] = airnode;
} else {
vm->m_data[i] = airnode;
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
}
}
}
}
}
inline bool CavesRandomWalk::isPosAboveSurface(v3s16 p)
{
if (heightmap != NULL &&
p.Z >= node_min.Z && p.Z <= node_max.Z &&
p.X >= node_min.X && p.X <= node_max.X) {
u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X);
if (heightmap[index] < p.Y)
return true;
} else if (p.Y > water_level) {
return true;
}
return false;
}
////
//// CavesV6
////
CavesV6::CavesV6(const NodeDefManager *ndef, GenerateNotifier *gennotify,
int water_level, content_t water_source, content_t lava_source)
{
assert(ndef);
this->ndef = ndef;
this->gennotify = gennotify;
this->water_level = water_level;
c_water_source = water_source;
if (c_water_source == CONTENT_IGNORE)
c_water_source = ndef->getId("mapgen_water_source");
if (c_water_source == CONTENT_IGNORE)
c_water_source = CONTENT_AIR;
c_lava_source = lava_source;
if (c_lava_source == CONTENT_IGNORE)
c_lava_source = ndef->getId("mapgen_lava_source");
if (c_lava_source == CONTENT_IGNORE)
c_lava_source = CONTENT_AIR;
}
void CavesV6::makeCave(MMVManip *vm, v3s16 nmin, v3s16 nmax,
PseudoRandom *ps, PseudoRandom *ps2,
bool is_large_cave, int max_stone_height, s16 *heightmap)
{
assert(vm);
assert(ps);
assert(ps2);
this->vm = vm;
this->ps = ps;
this->ps2 = ps2;
this->node_min = nmin;
this->node_max = nmax;
this->heightmap = heightmap;
this->large_cave = is_large_cave;
this->ystride = nmax.X - nmin.X + 1;
// Set initial parameters from randomness
min_tunnel_diameter = 2;
max_tunnel_diameter = ps->range(2, 6);
int dswitchint = ps->range(1, 14);
if (large_cave) {
part_max_length_rs = ps->range(2, 4);
tunnel_routepoints = ps->range(5, ps->range(15, 30));
min_tunnel_diameter = 5;
max_tunnel_diameter = ps->range(7, ps->range(8, 24));
} else {
part_max_length_rs = ps->range(2, 9);
tunnel_routepoints = ps->range(10, ps->range(15, 30));
}
large_cave_is_flat = (ps->range(0, 1) == 0);
main_direction = v3f(0, 0, 0);
// Allowed route area size in nodes
ar = node_max - node_min + v3s16(1, 1, 1);
// Area starting point in nodes
of = node_min;
// Allow a bit more
//(this should be more than the maximum radius of the tunnel)
const s16 max_spread_amount = MAP_BLOCKSIZE;
const s16 insure = 10;
s16 more = MYMAX(max_spread_amount - max_tunnel_diameter / 2 - insure, 1);
ar += v3s16(1, 0, 1) * more * 2;
of -= v3s16(1, 0, 1) * more;
route_y_min = 0;
// Allow half a diameter + 7 over stone surface
route_y_max = -of.Y + max_stone_height + max_tunnel_diameter / 2 + 7;
// Limit maximum to area
route_y_max = rangelim(route_y_max, 0, ar.Y - 1);
if (large_cave) {
s16 minpos = 0;
if (node_min.Y < water_level && node_max.Y > water_level) {
minpos = water_level - max_tunnel_diameter / 3 - of.Y;
route_y_max = water_level + max_tunnel_diameter / 3 - of.Y;
}
route_y_min = ps->range(minpos, minpos + max_tunnel_diameter);
route_y_min = rangelim(route_y_min, 0, route_y_max);
}
s16 route_start_y_min = route_y_min;
s16 route_start_y_max = route_y_max;
route_start_y_min = rangelim(route_start_y_min, 0, ar.Y - 1);
route_start_y_max = rangelim(route_start_y_max, route_start_y_min, ar.Y - 1);
// Randomize starting position
orp.Z = (float)(ps->next() % ar.Z) + 0.5f;
orp.Y = (float)(ps->range(route_start_y_min, route_start_y_max)) + 0.5f;
orp.X = (float)(ps->next() % ar.X) + 0.5f;
// Add generation notify begin event
if (gennotify != NULL) {
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_BEGIN : GENNOTIFY_CAVE_BEGIN;
gennotify->addEvent(notifytype, abs_pos);
}
// Generate some tunnel starting from orp
for (u16 j = 0; j < tunnel_routepoints; j++)
makeTunnel(j % dswitchint == 0);
// Add generation notify end event
if (gennotify != NULL) {
v3s16 abs_pos(of.X + orp.X, of.Y + orp.Y, of.Z + orp.Z);
GenNotifyType notifytype = large_cave ?
GENNOTIFY_LARGECAVE_END : GENNOTIFY_CAVE_END;
gennotify->addEvent(notifytype, abs_pos);
}
}
void CavesV6::makeTunnel(bool dirswitch)
{
if (dirswitch && !large_cave) {
main_direction.Z = ((float)(ps->next() % 20) - (float)10) / 10;
main_direction.Y = ((float)(ps->next() % 20) - (float)10) / 30;
main_direction.X = ((float)(ps->next() % 20) - (float)10) / 10;
main_direction *= (float)ps->range(0, 10) / 10;
}
// Randomize size
s16 min_d = min_tunnel_diameter;
s16 max_d = max_tunnel_diameter;
rs = ps->range(min_d, max_d);
s16 rs_part_max_length_rs = rs * part_max_length_rs;
v3s16 maxlen;
if (large_cave) {
maxlen = v3s16(
rs_part_max_length_rs,
rs_part_max_length_rs / 2,
rs_part_max_length_rs
);
} else {
maxlen = v3s16(
rs_part_max_length_rs,
ps->range(1, rs_part_max_length_rs),
rs_part_max_length_rs
);
}
v3f vec;
vec.Z = (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2;
vec.Y = (float)(ps->next() % maxlen.Y) - (float)maxlen.Y / 2;
vec.X = (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2;
// Jump downward sometimes
if (!large_cave && ps->range(0, 12) == 0) {
vec.Z = (float)(ps->next() % maxlen.Z) - (float)maxlen.Z / 2;
vec.Y = (float)(ps->next() % (maxlen.Y * 2)) - (float)maxlen.Y;
vec.X = (float)(ps->next() % maxlen.X) - (float)maxlen.X / 2;
}
// Do not make caves that are entirely above ground, to fix shadow bugs
// caused by overgenerated large caves.
// It is only necessary to check the startpoint and endpoint.
v3s16 p1 = v3s16(orp.X, orp.Y, orp.Z) + of + rs / 2;
v3s16 p2 = v3s16(vec.X, vec.Y, vec.Z) + p1;
// If startpoint and endpoint are above ground, disable placement of nodes
// in carveRoute while still running all PseudoRandom calls to ensure caves
// are consistent with existing worlds.
bool tunnel_above_ground =
p1.Y > getSurfaceFromHeightmap(p1) &&
p2.Y > getSurfaceFromHeightmap(p2);
vec += main_direction;
v3f rp = orp + vec;
if (rp.X < 0)
rp.X = 0;
else if (rp.X >= ar.X)
rp.X = ar.X - 1;
if (rp.Y < route_y_min)
rp.Y = route_y_min;
else if (rp.Y >= route_y_max)
rp.Y = route_y_max - 1;
if (rp.Z < 0)
rp.Z = 0;
else if (rp.Z >= ar.Z)
rp.Z = ar.Z - 1;
vec = rp - orp;
float veclen = vec.getLength();
// As odd as it sounds, veclen is *exactly* 0.0 sometimes, causing a FPE
if (veclen < 0.05f)
veclen = 1.0f;
// Every second section is rough
bool randomize_xz = (ps2->range(1, 2) == 1);
// Carve routes
for (float f = 0.f; f < 1.0f; f += 1.0f / veclen)
carveRoute(vec, f, randomize_xz, tunnel_above_ground);
orp = rp;
}
void CavesV6::carveRoute(v3f vec, float f, bool randomize_xz,
bool tunnel_above_ground)
{
MapNode airnode(CONTENT_AIR);
MapNode waternode(c_water_source);
MapNode lavanode(c_lava_source);
v3s16 startp(orp.X, orp.Y, orp.Z);
startp += of;
v3f fp = orp + vec * f;
fp.X += 0.1f * ps->range(-10, 10);
fp.Z += 0.1f * ps->range(-10, 10);
v3s16 cp(fp.X, fp.Y, fp.Z);
s16 d0 = -rs / 2;
s16 d1 = d0 + rs;
if (randomize_xz) {
d0 += ps->range(-1, 1);
d1 += ps->range(-1, 1);
}
for (s16 z0 = d0; z0 <= d1; z0++) {
s16 si = rs / 2 - MYMAX(0, abs(z0) - rs / 7 - 1);
for (s16 x0 = -si - ps->range(0,1); x0 <= si - 1 + ps->range(0,1); x0++) {
if (tunnel_above_ground)
continue;
s16 maxabsxz = MYMAX(abs(x0), abs(z0));
s16 si2 = rs / 2 - MYMAX(0, maxabsxz - rs / 7 - 1);
for (s16 y0 = -si2; y0 <= si2; y0++) {
if (large_cave_is_flat) {
// Make large caves not so tall
if (rs > 7 && abs(y0) >= rs / 3)
continue;
}
v3s16 p(cp.X + x0, cp.Y + y0, cp.Z + z0);
p += of;
if (!vm->m_area.contains(p))
continue;
u32 i = vm->m_area.index(p);
content_t c = vm->m_data[i].getContent();
if (!ndef->get(c).is_ground_content)
continue;
if (large_cave) {
int full_ymin = node_min.Y - MAP_BLOCKSIZE;
int full_ymax = node_max.Y + MAP_BLOCKSIZE;
if (full_ymin < water_level && full_ymax > water_level) {
vm->m_data[i] = (p.Y <= water_level) ? waternode : airnode;
} else if (full_ymax < water_level) {
vm->m_data[i] = (p.Y < startp.Y - 2) ? lavanode : airnode;
} else {
vm->m_data[i] = airnode;
}
} else {
if (c == CONTENT_AIR)
continue;
vm->m_data[i] = airnode;
vm->m_flags[i] |= VMANIP_FLAG_CAVE;
}
}
}
}
}
inline s16 CavesV6::getSurfaceFromHeightmap(v3s16 p)
{
if (heightmap != NULL &&
p.Z >= node_min.Z && p.Z <= node_max.Z &&
p.X >= node_min.X && p.X <= node_max.X) {
u32 index = (p.Z - node_min.Z) * ystride + (p.X - node_min.X);
return heightmap[index];
}
return water_level;
}
|