241 lines
9.7 KiB
JavaScript
241 lines
9.7 KiB
JavaScript
import {Noise} from "noisejs";
|
|
import { Rectangle } from "../../pixi/pixi.mjs";
|
|
import { BC_CAMERA, BC_CHUNKS_SETTINGS, BC_CURRENT_SCENE, BC_SPRITES_SETTINGS, BC_TERRAIN_SETTINGS, PRNG } from "../GlobalVariables/GlobalVariables";
|
|
import { NumberCue, RGBColor } from "../Utils/DataTypes.utils";
|
|
import { ChunkStorageTypes, WorldChunk } from "./WorldChunk/WorldGenChunk";
|
|
import { TerrainTile, TerrainTileProps } from "./WorldObjects/TerrainTile/TerrainTile";
|
|
import { clampNumber } from "../Utils/Math.utils";
|
|
import { addGameObjectToGameState } from "../GameState/GameState";
|
|
import { VegetationTile, VegetationTileProps } from "./WorldObjects/VegetationTile/VegetationTile";
|
|
import { WorldChunksVisibilityUpdater } from "./WorldChunksVisibilityUpdater/WorldChunksVisibilityUpdater";
|
|
|
|
/**
|
|
* @type Map<String, WorldChunk>
|
|
*/
|
|
const WorldChunksStorage = new Map();
|
|
|
|
|
|
/* #### REWRITE PART START ####*/
|
|
const terrainSpriteList = {
|
|
0: { x: 21, y: 21 }, //water
|
|
1: { x: 2, y: 21 }, //sand
|
|
2: { x: 2, y: 2 }, //grass
|
|
3: { x: 21, y: 2 }, //stone
|
|
};
|
|
const terrainTypeList = {
|
|
0: "ter_water", //water
|
|
1: "ter_sand", //sand
|
|
2: "ter_grass", //grass
|
|
3: "ter_stone", //stone
|
|
};
|
|
const grassVegetationSpriteList = {
|
|
0: { x: 10, y: 11 },
|
|
1: { x: 11, y: 11 },
|
|
2: { x: 12, y: 11 },
|
|
3: { x: 13, y: 11 },
|
|
4: { x: 14, y: 11 },
|
|
5: { x: 15, y: 11 },
|
|
6: { x: 16, y: 11 },
|
|
7: { x: 17, y: 11 },
|
|
8: { x: 18, y: 11 },
|
|
9: { x: 19, y: 11 },
|
|
10: { x: 0, y: 12 },
|
|
11: { x: 1, y: 12 },
|
|
12: { x: 2, y: 12 },
|
|
13: { x: 3, y: 12 },
|
|
14: { x: 7, y: 13 },
|
|
15: { x: 7, y: 12 },
|
|
16: { x: 8, y: 12 },
|
|
17: { x: 9, y: 12 },
|
|
};
|
|
const grassVegResourcesList = {
|
|
0: { type: "grass", num: 10 / 5 },
|
|
1: { type: "grass", num: 9 / 5 },
|
|
2: { type: "grass", num: 8 / 5 },
|
|
3: { type: "grass", num: 7 / 5 },
|
|
4: { type: "grass", num: 4 / 5 },
|
|
5: { type: "grass", num: 4 / 5 },
|
|
6: { type: "grass", num: 5 / 5 },
|
|
7: { type: "grass", num: 3 / 5 },
|
|
8: { type: "grass", num: 2 / 5 },
|
|
9: { type: "grass", num: 1 / 5 },
|
|
10: { type: "grass", num: 2 / 5 },
|
|
11: { type: "grass", num: 2 / 5 },
|
|
12: { type: "grass", num: 2 / 5 },
|
|
13: { type: "grass", num: 2 / 5 },
|
|
14: { type: "stone", num: 1 / 5 },
|
|
15: { type: "wood", num: 2 / 5 },
|
|
16: { type: "wood", num: 2 / 5 },
|
|
17: { type: "wood", num: 2 / 5 },
|
|
};
|
|
|
|
export function worldCoordinatesToChunkIndex(x, y) {
|
|
let w = BC_CHUNKS_SETTINGS.width * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
let h = BC_CHUNKS_SETTINGS.height * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
return { x: Math.floor(x / w), y: Math.floor(y / h) };
|
|
}
|
|
export function worldCoordinatesToChunkIndexesCoordinates(x, y) {
|
|
let ws = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
let hs = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
return { x: Math.floor(x / ws), y: Math.floor(y / hs) };
|
|
}
|
|
export function worldCoordinatesToChunkLocalCoordinates(x, y) {
|
|
let ws = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
let hs = BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
if (x < 0 && y >= 0)
|
|
return {
|
|
x: BC_CHUNKS_SETTINGS.width - (Math.floor(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width) - 1,
|
|
y: Math.floor(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height,
|
|
};
|
|
else if (x < 0 && y < 0)
|
|
return {
|
|
x: BC_CHUNKS_SETTINGS.width - (Math.floor(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width) - 1,
|
|
y: BC_CHUNKS_SETTINGS.height - (Math.floor(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height) - 1,
|
|
};
|
|
else if (x > 0 && y < 0)
|
|
return {
|
|
x: Math.floor(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width,
|
|
y: BC_CHUNKS_SETTINGS.height - (Math.floor(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height) - 1,
|
|
};
|
|
else
|
|
return {
|
|
x: Math.floor(Math.abs(x) / ws) % BC_CHUNKS_SETTINGS.width,
|
|
y: Math.floor(Math.abs(y) / hs) % BC_CHUNKS_SETTINGS.height,
|
|
};
|
|
}
|
|
|
|
export function getWorldChunkAt(xWorld, yWorld) {
|
|
let t = worldCoordinatesToChunkIndex(xWorld, yWorld);
|
|
return WorldChunksStorage.get(t.x+"_"+t.y);
|
|
}
|
|
|
|
export function getWorldChunkById(id) {
|
|
return WorldChunksStorage.get(id);
|
|
}
|
|
|
|
export function worldChunkExists(id) {
|
|
return WorldChunksStorage.has(id);
|
|
}
|
|
|
|
export function setWorldChunkById(chunk, id) {
|
|
WorldChunksStorage.set(id, chunk);
|
|
}
|
|
|
|
let noise = new Noise(Math.floor(PRNG() * 188822321));
|
|
let noiseErosion = new Noise(Math.floor(PRNG() * 327749029));
|
|
let noiseBiomes = new Noise(Math.floor(PRNG() * 927472011));
|
|
|
|
let terrainCue = new NumberCue([0, 1, 2, 3, 3], [0.0, 0.45, 0.5, 0.9, 1.0]);
|
|
let terrainTintCue = new NumberCue([0.9, 1, 1, 0.95, 0.9, 1, 0.93, 1], [0.0, 0.45, 0.45, 0.5, 0.5, 0.9, 0.9, 1.0]);
|
|
|
|
/**
|
|
*
|
|
* @param {WorldChunk} chunk chunk to fill
|
|
* @param {Number} x ceiled coordinates of left-upper corner
|
|
* @param {Number} y ceiled coordinates of left-upper corner
|
|
*/
|
|
export function fillWorldGenChunk(chunk, x, y) {
|
|
let ii = 0;
|
|
let jj = 0;
|
|
for (let i = BC_CHUNKS_SETTINGS.width * x; i < BC_CHUNKS_SETTINGS.width * (x + 1); i++) {
|
|
jj = 0;
|
|
for (let j = BC_CHUNKS_SETTINGS.height * y; j < BC_CHUNKS_SETTINGS.height * (y + 1); j++) {
|
|
let res = (noise.simplex2(i * 0.025, j * 0.025) + 1) / 2;
|
|
let resR = (noiseErosion.simplex2(i * 0.3, j * 0.3) + 1) / 2;
|
|
let resB = (noiseBiomes.simplex2(i * 0.01, j * 0.01) + 1) / 2;
|
|
if (resB > 0.7) {
|
|
res = clampNumber(res - resR / 4, 0.0, 0.99);
|
|
}
|
|
if (resB > 0.5 && res < 0.9 && res >= 0.5) {
|
|
res = clampNumber(res + resR / 4, 0.0, 0.99);
|
|
}
|
|
|
|
let sTint = new RGBColor(255, 255, 255).multiplyByNumber(terrainTintCue.getValueAt(res)).toNumber();
|
|
res = Math.floor(terrainCue.getValueAt(res));
|
|
|
|
let terrainTile = new TerrainTile(false);
|
|
// console.log(terrainTile.isTickEnabled());
|
|
terrainTile.spriteSheetPath = "assets/images/world/world_terrain_atlas.png";
|
|
terrainTile.frame = new Rectangle(terrainSpriteList[res].x, terrainSpriteList[res].y, 16, 16);
|
|
terrainTile.props = new TerrainTileProps(terrainTypeList[res], res*5);
|
|
|
|
addGameObjectToGameState(terrainTile);
|
|
|
|
terrainTile.drawObject.tint = sTint;
|
|
terrainTile.drawObject.zIndex = 1;
|
|
terrainTile.drawObject.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
|
terrainTile.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
|
|
|
chunk.addToChunk(terrainTile, ChunkStorageTypes.TYPE_TERRAIN, i+"_"+j);
|
|
|
|
if (res === 2 && PRNG() > 0.9) {
|
|
let rv = Math.floor(PRNG() * 18);
|
|
|
|
let vegetationTile = new VegetationTile(false);
|
|
// console.log(vegetationTile.isTickEnabled());
|
|
vegetationTile.spriteSheetPath = "assets/images/world/vegetation_ts.png";
|
|
vegetationTile.frame = new Rectangle(16 * grassVegetationSpriteList[rv].x, 16 * grassVegetationSpriteList[rv].y, 16, 16);
|
|
vegetationTile.props = new VegetationTileProps("vegetation", grassVegResourcesList[rv]);
|
|
|
|
addGameObjectToGameState(vegetationTile);
|
|
|
|
vegetationTile.drawObject.tint = sTint;
|
|
vegetationTile.drawObject.zIndex = 2;
|
|
vegetationTile.drawObject.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj);
|
|
vegetationTile.drawObject.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);
|
|
|
|
chunk.addToChunk(vegetationTile, ChunkStorageTypes.TYPE_VEGETATION, i+"_"+j);
|
|
|
|
jj++;
|
|
continue;
|
|
}
|
|
jj++;
|
|
}
|
|
ii++;
|
|
}
|
|
}
|
|
|
|
export function createFirstWorldChunks() {
|
|
let w = BC_CHUNKS_SETTINGS.width * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
let h = BC_CHUNKS_SETTINGS.height * BC_TERRAIN_SETTINGS.tileSize * BC_TERRAIN_SETTINGS.scale;
|
|
for (let i = -1; i < 2; i++) {
|
|
for (let j = -1; j < 2; j++) {
|
|
let chunkXCeiled = Math.floor((BC_CAMERA.position.x + w * i) / w);
|
|
let chunkYCeiled = Math.floor((BC_CAMERA.position.y + h * j) / h);
|
|
let chunkId = chunkXCeiled + "_" + chunkYCeiled;
|
|
|
|
let chunk = new WorldChunk(false);
|
|
chunk.drawObject.position.set(w * chunkXCeiled, h * chunkYCeiled);
|
|
|
|
BC_CURRENT_SCENE.addObjectToSceneWithInitialization(chunk);
|
|
|
|
fillWorldGenChunk(chunk, chunkXCeiled, chunkYCeiled);
|
|
WorldChunksStorage.set(chunkId, chunk);
|
|
// console.log(chunkId);
|
|
// let chunkRef = createWorldChunkContainer();
|
|
// chunkRef.isRenderGroup = true;
|
|
// chunkRef.position.set(w * chunkXCeiled, h * chunkYCeiled);
|
|
// console.log(w * chunkXCeiled, h * chunkYCeiled);
|
|
// let chunk0 = new WorldChunk(
|
|
// chunkRef,
|
|
// chunkRef.getChildAt(0),
|
|
// chunkRef.getChildAt(1),
|
|
// chunkRef.getChildAt(2),
|
|
// // chunkRef.getChildAt(3),
|
|
// new Vault("terrain"),
|
|
// new Vault("vegetation"),
|
|
// new Vault("buildings")
|
|
// );
|
|
|
|
// fillChunk(chunk0, chunkXCeiled, chunkYCeiled);
|
|
// WORLD_CHUNKS.set(chunkId, chunk0);
|
|
// chunkRef.visible = false;
|
|
// addToViewport(chunkRef);
|
|
// console.log(WORLD_CHUNKS)
|
|
// console.log(chunkXCeiled, chunkYCeiled);
|
|
}
|
|
}
|
|
WorldChunksVisibilityUpdater.enableAutoWorldChunksGeneration = true;
|
|
}
|
|
|
|
/* #### REWRITE PART END ####*/ |