UNPKG

@aresrpg/aresrpg-sdk

Version:

General SDK to interract with AresRPG

216 lines (193 loc) 5.92 kB
import { BiomeType, BlockType, WorldLocals, WorldSeed, } from '@aresrpg/aresrpg-world' import TEMPERATE from './biomes/temperate.js' import GRASSLAND from './biomes/grassland.js' import TROPICAL from './biomes/tropical.js' import SWAMP from './biomes/swamp.js' import DESERT from './biomes/desert.js' import TAIGA from './biomes/taiga.js' import ARCTIC from './biomes/arctic.js' import SCORCHED from './biomes/scorched.js' import GLACIER from './biomes/glacier.js' import { BLOCKS, SCHEMATICS_BLOCKS } from './blocks.js' // Convert hex string to number export const hex_to_int = value => { if (typeof value === 'number') return value if (typeof value === 'string') return parseInt(value.replace('#', ''), 16) if (typeof value === 'object' && value !== null) { return typeof value.color === 'string' ? parseInt(value.color.replace('#', ''), 16) : value.color } throw new Error(`Invalid color value: ${value}`) } // Extract unique colors from block definitions const unique_block_colors = [ ...new Set( Object.values({ ...BLOCKS, ...SCHEMATICS_BLOCKS, }), ), ] const normalize_material = value => { if (typeof value === 'object' && value !== null) { return { color: hex_to_int(value.color), emission: value.emission ?? 0, } } return hex_to_int(value) } // Generate new block type entries for each unique color/material const additional_block_types = unique_block_colors.reduce( (mapping, value, index) => ({ ...mapping, [BlockType.LAST_PLACEHOLDER + index]: normalize_material(value), }), {}, ) function map_blocks_to_type(biome) { return Object.entries(biome).reduce((acc, [key, value]) => { // For types that are strings (hex colors) or objects with color property const type = typeof value.type === 'object' || typeof value.type === 'string' ? color_to_block_type[hex_to_int(value.type)] : value.type // Same for subtypes const subtype = typeof value.subtype === 'object' || typeof value.subtype === 'string' ? color_to_block_type[hex_to_int(value.subtype)] : value.subtype // If we get undefined, fallback to original value (in case mapping fails) return { ...acc, [key]: { ...value, type: type !== undefined ? type : value.type, subtype: subtype !== undefined ? subtype : value.subtype, }, } }, {}) } // Schematics blocks mapping as NUMBER (block type) to NUMBER (color) // { 0: 0x000000 } export const BLOCKS_COLOR_MAPPING = { [BlockType.NONE]: 0x000000, [BlockType.HOLE]: 0x000000, [BlockType.BEDROCK]: 0xababab, [BlockType.WATER]: 0x74ccf4, [BlockType.ICE]: { color: 0x74ccf5, emission: 0.1 }, [BlockType.MUD]: 0x795548, [BlockType.TRUNK]: 0x795549, [BlockType.SAND]: 0xc2b280, [BlockType.GRASS]: 0x41980a, [BlockType.ROCK]: 0xababab, [BlockType.SNOW]: 0xe5e5e5, [BlockType.FOLIAGE_LIGHT]: 0x558b2f, [BlockType.FOLIAGE_DARK]: 0x33691e, ...additional_block_types, } // Create a reverse mapping from color to block type id for efficient lookup export const color_to_block_type = Object.entries(BLOCKS_COLOR_MAPPING).reduce( (type_lookup, [type_id, material]) => ({ ...type_lookup, [typeof material === 'object' ? material.color : material]: +type_id, }), {}, ) // TODO: maybe this is not needed and could be ignored in the world? const ignored_blocks = [ 'air', 'jungle_fence', 'grass', 'player_wall_head', 'cobbled_deepslate', 'iron_trapdoor', 'iron_bars', 'stick', 'stone_brick_slab', ] // Schematics blocks mapping as STRING (block name) to NUMBER (block type) // { 'air': 0 } export const SCHEMATICS_BLOCKS_MAPPING = { air: BlockType.NONE, ...Object.fromEntries( ignored_blocks.map(block_name => [block_name, BlockType.NONE]), ), ...Object.entries({ ...BLOCKS, ...SCHEMATICS_BLOCKS, }).reduce( (block_mappings, [block_name, color]) => ({ ...block_mappings, [block_name.toLowerCase()]: color_to_block_type[hex_to_int(color)], }), {}, ), } export const LANDSCAPE = { [BiomeType.Arctic]: map_blocks_to_type(ARCTIC), [BiomeType.Desert]: map_blocks_to_type(DESERT), [BiomeType.Glacier]: map_blocks_to_type(GLACIER), [BiomeType.Grassland]: map_blocks_to_type(GRASSLAND), [BiomeType.Scorched]: map_blocks_to_type(SCORCHED), [BiomeType.Swamp]: map_blocks_to_type(SWAMP), [BiomeType.Taiga]: map_blocks_to_type(TAIGA), [BiomeType.Temperate]: map_blocks_to_type(TEMPERATE), [BiomeType.Tropical]: map_blocks_to_type(TROPICAL), } export const create_world_settings = schematics_files => { const settings = new WorldLocals() settings.rawSettings = { ...settings.rawSettings, seeds: { [WorldSeed.Global]: 'aresrpg', [WorldSeed.Heightmap]: 'heightmap', [WorldSeed.Amplitude]: 'amplitude', [WorldSeed.Heatmap]: 'heatmap', [WorldSeed.Rainmap]: 'rainmap', [WorldSeed.RandomPos]: 'random_pos', [WorldSeed.Spawn]: 'spawn', [WorldSeed.Density]: 'density', }, chunks: { powSize: 6, // idRange verticalRange: { bottomId: 0, topId: 5, }, }, items: { schematics: { globalBlocksMapping: SCHEMATICS_BLOCKS_MAPPING, localBlocksMapping: {}, filesIndex: schematics_files, }, proceduralConfigs: {}, }, heightmap: { spreading: 0.42, harmonics: 6, }, biomes: { rawConf: LANDSCAPE, seaLevel: 76, periodicity: 10, // size of the biomes repartition: { centralHalfSegment: 0.07, // half range of central segment in proportion to first and last symetrical segments transitionHalfRange: 0.05, // bilinear interpolation: 0 = no transition, 0.05 = max transition }, }, boards: { radius: 15, thickness: 3, }, } return settings }