HollowBond/Public/ecma/Builders/HolesBuilder.ecma.js

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;
})();