141 lines
6.8 KiB
JavaScript
141 lines
6.8 KiB
JavaScript
"use strict";
|
|
|
|
const HolesBuilder = (function(){
|
|
|
|
const HolesBuilder = function(hollow_bond){
|
|
|
|
const add = (chunk, inputs) => {
|
|
|
|
const id = HoleModel.get_id(inputs.xf, inputs.yf, inputs.zf, inputs.xt, inputs.yt, inputs.zt),
|
|
hole = (
|
|
chunk.holes[id] ||
|
|
hollow_bond.map.holes[id] ||
|
|
new HoleModel(hollow_bond, inputs)
|
|
);
|
|
|
|
chunk.holes[id] = hole;
|
|
chunk.occupy(hole.xf, hole.yf, hole.zf, hole.xt, hole.yt, hole.zt, "hole", id);
|
|
|
|
hole.stairs.forEach(stair => {
|
|
chunk.stairs[stair.id] = stair;
|
|
});
|
|
|
|
return hole;
|
|
};
|
|
|
|
this.generate_seam = chunk => {
|
|
|
|
[[chunk.yf, "down"], [chunk.yt, "up"]].forEach(([plane_y, neighbor]) => {
|
|
if(!chunk.neighbors[neighbor])
|
|
return;
|
|
|
|
const hole_attempts = Math.floor(hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, 0) * hollow_bond.hole_seam_tries);
|
|
|
|
for(let i = 0; i < hole_attempts; i ++){
|
|
|
|
const width = Common.random_decay(
|
|
hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, i * 7 + 1),
|
|
hollow_bond.hole_minimum_size,
|
|
hollow_bond.hole_maximum_size,
|
|
hollow_bond.hole_size_decay
|
|
),
|
|
depth = Common.random_decay(
|
|
hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, i * 7 + 2),
|
|
hollow_bond.hole_minimum_size,
|
|
hollow_bond.hole_maximum_size,
|
|
hollow_bond.hole_size_decay
|
|
),
|
|
height = Common.random_decay(
|
|
hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, i * 7 + 3),
|
|
hollow_bond.hole_minimum_height,
|
|
hollow_bond.hole_maximum_height,
|
|
hollow_bond.hole_height_decay
|
|
),
|
|
available_x = hollow_bond.chunk_size - width - hollow_bond.hole_margin * 2,
|
|
available_z = hollow_bond.chunk_size - depth - hollow_bond.hole_margin * 2;
|
|
|
|
if(available_x <= 0 || available_z <= 0)
|
|
continue;
|
|
|
|
const horizontal_xf = chunk.xf + hollow_bond.hole_margin + Math.floor(hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, i * 7 + 5) * available_x),
|
|
horizontal_xt = horizontal_xf + width,
|
|
horizontal_zf = chunk.zf + hollow_bond.hole_margin + Math.floor(hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, i * 7 + 6) * available_z),
|
|
horizontal_zt = horizontal_zf + depth,
|
|
penetration = Math.floor(hollow_bond.hash.seam_horizontal(chunk.xf, plane_y, chunk.zf, chunk.xt, chunk.zt, i * 7 + 4) * (height - 1)) + 1,
|
|
horizontal_yf = plane_y - penetration,
|
|
horizontal_yt = horizontal_yf + height;
|
|
|
|
chunk.is_occupied(horizontal_xf, horizontal_yf, horizontal_zf, horizontal_xt, horizontal_yt, horizontal_zt) || add(chunk, {
|
|
xf : horizontal_xf,
|
|
yf : horizontal_yf,
|
|
zf : horizontal_zf,
|
|
xt : horizontal_xt,
|
|
yt : horizontal_yt,
|
|
zt : horizontal_zt
|
|
});
|
|
|
|
};
|
|
|
|
});
|
|
|
|
return chunk.holes;
|
|
};
|
|
|
|
this.generate_internal = chunk => {
|
|
|
|
for(let py = chunk.yf + 1; py < chunk.yt - hollow_bond.hole_minimum_height; py += hollow_bond.hole_floor_step){
|
|
if(hollow_bond.hash.hole_internal(chunk.xf, py, chunk.zf, chunk.xt, py + 1, chunk.zt, 0) > hollow_bond.internal_hole_probability)
|
|
continue;
|
|
|
|
const width = Common.random_decay(
|
|
hollow_bond.hash.hole_internal(chunk.xf, py, chunk.zf, chunk.xt, py + 1, chunk.zt, 1),
|
|
hollow_bond.hole_minimum_size,
|
|
hollow_bond.hole_maximum_size,
|
|
hollow_bond.hole_size_decay
|
|
),
|
|
depth = Common.random_decay(
|
|
hollow_bond.hash.hole_internal(chunk.xf, py, chunk.zf, chunk.xt, py + 1, chunk.zt, 2),
|
|
hollow_bond.hole_minimum_size,
|
|
hollow_bond.hole_maximum_size,
|
|
hollow_bond.hole_size_decay
|
|
),
|
|
raw_height = Common.random_decay(
|
|
hollow_bond.hash.hole_internal(chunk.xf, py, chunk.zf, chunk.xt, py + 1, chunk.zt, 3),
|
|
hollow_bond.hole_minimum_height,
|
|
hollow_bond.hole_maximum_height,
|
|
hollow_bond.hole_height_decay
|
|
),
|
|
available_x = hollow_bond.chunk_size - width - hollow_bond.hole_margin * 2,
|
|
available_z = hollow_bond.chunk_size - depth - hollow_bond.hole_margin * 2;
|
|
|
|
if(available_x <= 0 || available_z <= 0)
|
|
continue;
|
|
|
|
const internal_xf = chunk.xf + hollow_bond.hole_margin + Math.floor(hollow_bond.hash.hole_internal(chunk.xf, py, chunk.zf, chunk.xt, py + 1, chunk.zt, 4) * available_x),
|
|
internal_xt = internal_xf + width,
|
|
internal_zf = chunk.zf + hollow_bond.hole_margin + Math.floor(hollow_bond.hash.hole_internal(chunk.xf, py, chunk.zf, chunk.xt, py + 1, chunk.zt, 5) * available_z),
|
|
internal_zt = internal_zf + depth,
|
|
internal_yf = py,
|
|
internal_yt = Math.min(chunk.yt - 1, internal_yf + raw_height);
|
|
|
|
if((internal_yt - internal_yf) < hollow_bond.hole_minimum_height)
|
|
continue;
|
|
|
|
chunk.is_occupied(internal_xf, internal_yf, internal_zf, internal_xt, internal_yt, internal_zt) || add(chunk, {
|
|
xf : internal_xf,
|
|
yf : internal_yf,
|
|
zf : internal_zf,
|
|
xt : internal_xt,
|
|
yt : internal_yt,
|
|
zt : internal_zt
|
|
});
|
|
|
|
};
|
|
|
|
return chunk.holes;
|
|
};
|
|
|
|
};
|
|
|
|
return HolesBuilder;
|
|
})(); |