diff --git a/src/app/partners/Lithostitched.ts b/src/app/partners/Lithostitched.ts new file mode 100644 index 00000000..01b14f6f --- /dev/null +++ b/src/app/partners/Lithostitched.ts @@ -0,0 +1,229 @@ +import type { CollectionRegistry, ResourceType, SchemaRegistry } from '@mcschema/core' +import { BooleanNode, Case, ChoiceNode, ListNode, Mod, NumberNode, ObjectNode, Opt, Reference as RawReference, StringNode as RawStringNode, Switch } from '@mcschema/core' + + +const ID = 'lithostitched' + +export function initLithostitched(schemas: SchemaRegistry, collections: CollectionRegistry) { + const Reference = RawReference.bind(undefined, schemas) + const StringNode = RawStringNode.bind(undefined, collections) + + const Tag = (id: Exclude) => + ChoiceNode( + [ + { + type: 'string', + node: StringNode({ + validator: 'resource', + params: { pool: id, allowTag: true }, + }), + change: (v: unknown) => { + if ( + Array.isArray(v) && + typeof v[0] === 'string' && + !v[0].startsWith('#') + ) { + return v[0] + } + return undefined + }, + }, + { + type: 'list', + node: ListNode( + StringNode({ validator: 'resource', params: { pool: id } }) + ), + change: (v: unknown) => { + if (typeof v === 'string' && !v.startsWith('#')) { + return [v] + } + return [] + }, + }, + ], + { choiceContext: 'tag' } + ) + + // Worldgen Modifiers + const MobCategorySpawnSettings = Mod( + ObjectNode({ + type: StringNode({ + validator: 'resource', + params: { pool: 'entity_type' }, + }), + weight: NumberNode({ integer: true }), + minCount: NumberNode({ integer: true }), + maxCount: NumberNode({ integer: true }), + }), + { + category: () => 'pool', + default: () => [ + { + type: 'minecraft:bat', + weight: 1, + }, + ], + } + ) + + collections.register(`${ID}:modifier_type`, [ + 'lithostitched:add_biome_spawns', + 'lithostitched:add_features', + 'lithostitched:add_structure_set_entries', + 'lithostitched:add_surface_rule', + 'lithostitched:add_template_pool_elements', + 'lithostitched:no_op', + 'lithostitched:redirect_feature', + 'lithostitched:remove_biome_spawns', + 'lithostitched:remove_features', + 'lithostitched:remove_structures_from_structure_set', + 'lithostitched:replace_climate', + 'lithostitched:replace_effects', + ]) + + collections.register(`${ID}:modifier_predicate_type`, [ + 'lithostitched:all_of', + 'lithostitched:any_of', + 'lithostitched:mod_loaded', + 'lithostitched:not', + 'lithostitched:true', + ]) + + schemas.register(`${ID}:worldgen_modifier`, Mod(ObjectNode({ + type: StringNode({ validator: 'resource', params: { pool: `${ID}:modifier_type` as any } }), + predicate: Opt(Reference(`${ID}:modifier_predicate`)), + [Switch]: [{ push: 'type' }], + [Case]: { + 'lithostitched:add_biome_spawns': { + biomes: Tag('$worldgen/biome'), + spawners: ChoiceNode([ + { + type: 'object', + node: MobCategorySpawnSettings, + change: (v: any) => v[0], + }, + { + type: 'list', + node: ListNode(MobCategorySpawnSettings), + change: (v: any) => Array(v), + }, + ]), + }, + 'lithostitched:add_features': { + biomes: Tag('$worldgen/biome'), + features: Tag('$worldgen/configured_feature'), + step: StringNode({ enum: 'decoration_step' }), + }, + 'lithostitched:add_structure_set_entries': { + structure_set: StringNode({ validator: 'resource', params: { pool: '$worldgen/structure_set' } }), + entries: ListNode( + ObjectNode({ + structure: StringNode({ validator: 'resource', params: { pool: '$worldgen/structure' } }), + weight: NumberNode({ integer: true, min: 1 }), + }) + ), + }, + 'lithostitched:add_surface_rule': { + levels: ListNode(StringNode({ validator: 'resource', params: { pool: '$dimension' } })), + surface_rule: Reference('material_rule'), + }, + 'lithostitched:add_template_pool_elements': { + template_pool: StringNode({ validator: 'resource', params: { pool: '$worldgen/template_pool' } }), + elements: ListNode( + Reference('template_weighted_element') + ), + }, + 'lithostitched:redirect_feature': { + placed_feature: StringNode({ validator: 'resource', params: { pool: '$worldgen/placed_feature' } }), + redirect_to: StringNode({ validator: 'resource', params: { pool: '$worldgen/configured_feature' } }), + }, + 'lithostitched:remove_biome_spawns': { + biomes: Tag('$worldgen/biome'), + mobs: Tag('entity_type'), + }, + 'lithostitched:remove_features': { + biomes: Tag('$worldgen/biome'), + features: Tag('$worldgen/configured_feature'), + step: StringNode({ enum: 'decoration_step' }), + }, + 'lithostitched:remove_structures_from_structure_set': { + structure_set: StringNode({ validator: 'resource', params: { pool: '$worldgen/structure_set' } }), + structures: ListNode( + StringNode({ validator: 'resource', params: { pool: '$worldgen/structure' } }) + ), + }, + 'lithostitched:replace_climate': { + biomes: Tag('$worldgen/biome'), + climate: ObjectNode({ + temperature: NumberNode(), + downfall: NumberNode(), + has_precipitation: BooleanNode(), + temperature_modifier: Opt(StringNode({ enum: ['none', 'frozen'] })), + }), + }, + 'lithostitched:replace_effects': { + biomes: Tag('$worldgen/biome'), + effects: ObjectNode({ + sky_color: Opt(NumberNode({ color: true })), + fog_color: Opt(NumberNode({ color: true })), + water_color: Opt(NumberNode({ color: true })), + water_fog_color: Opt(NumberNode({ color: true })), + grass_color: Opt(NumberNode({ color: true })), + foliage_color: Opt(NumberNode({ color: true })), + grass_color_modifier: Opt(StringNode({ enum: ['none', 'dark_forest', 'swamp'] })), + ambient_sound: Opt(StringNode()), + mood_sound: Opt(ObjectNode({ + sound: StringNode(), + tick_delay: NumberNode({ integer: true }), + block_search_extent: NumberNode({ integer: true }), + offset: NumberNode(), + })), + additions_sound: Opt(ObjectNode({ + sound: StringNode(), + tick_chance: NumberNode({ min: 0, max: 1 }), + })), + music: Opt(ObjectNode({ + sound: StringNode(), + min_delay: NumberNode({ integer: true, min: 0 }), + max_delay: NumberNode({ integer: true, min: 0 }), + replace_current_music: BooleanNode(), + })), + particle: Opt(ObjectNode({ + options: ObjectNode({ + type: StringNode(), + }), + probability: NumberNode({ min: 0, max: 1 }), + })), + }), + }, + }, + }, { context: `${ID}.worldgen_modifier`, disableSwitchContext: true }), { + default: () => ({ + type: `${ID}:add_features`, + biomes: '#minecraft:is_overworld', + features: 'example:ore_ruby', + step: 'underground_ores', + }), + })) + + schemas.register(`${ID}:modifier_predicate`, ObjectNode({ + type: StringNode({ validator: 'resource', params: { pool: `${ID}:modifier_predicate_type` as any } }), + [Switch]: [{ push: 'type' }], + [Case]: { + 'lithostitched:all_of': { + predicates: ListNode(Reference(`${ID}:modifier_predicate`)), + }, + 'lithostitched:any_of': { + predicates: ListNode(Reference(`${ID}:modifier_predicate`)), + }, + 'lithostitched:mod_loaded': { + mod_id: StringNode(), + }, + 'lithostitched:not': { + predicate: Reference(`${ID}:modifier_predicate`), + }, + }, + }, { + context: `${ID}.modifier_predicate`, disableSwitchContext: true, + })) +} diff --git a/src/app/partners/index.ts b/src/app/partners/index.ts index 7300a2c3..f43b3067 100644 --- a/src/app/partners/index.ts +++ b/src/app/partners/index.ts @@ -1,10 +1,13 @@ import type { CollectionRegistry, SchemaRegistry } from '@mcschema/core' import { initImmersiveWeathering } from './ImmersiveWeathering.js' +import { initLithostitched } from './Lithostitched.js' import { initObsidian } from './Obsidian.js' export * from './ImmersiveWeathering.js' +export * from './Lithostitched.js' export function initPartners(schemas: SchemaRegistry, collections: CollectionRegistry) { initImmersiveWeathering(schemas, collections) + initLithostitched(schemas, collections) initObsidian(schemas, collections) } diff --git a/src/app/partners/locales/en.json b/src/app/partners/locales/en.json index 7a05495d..154279ce 100644 --- a/src/app/partners/locales/en.json +++ b/src/app/partners/locales/en.json @@ -55,8 +55,24 @@ "immersive_weathering:rule_test.immersive_weathering:block_set_match": "Block set match", "immersive_weathering:rule_test.immersive_weathering:fluid_match": "Fluid match", "immersive_weathering:rule_test.immersive_weathering:tree_log": "Tree log", - "rule_test.blocks": "Blocks", - "rule_test.fluid": "Fluid", + + "lithostitched:modifier_type.lithostitched:add_biome_spawns": "Add biome spawns", + "lithostitched:modifier_type.lithostitched:add_features": "Add features", + "lithostitched:modifier_type.lithostitched:add_structure_set_entries": "Add structure set entries", + "lithostitched:modifier_type.lithostitched:add_surface_rule": "Add surface rule", + "lithostitched:modifier_type.lithostitched:add_template_pool_elements": "Add template pool elements", + "lithostitched:modifier_type.lithostitched:no_op": "Nothing", + "lithostitched:modifier_type.lithostitched:redirect_feature": "Redirect feature", + "lithostitched:modifier_type.lithostitched:remove_biome_spawns": "Remove biome spawns", + "lithostitched:modifier_type.lithostitched:remove_features": "Remove features", + "lithostitched:modifier_type.lithostitched:remove_structures_from_structure_set": "Remove structures from set", + "lithostitched:modifier_type.lithostitched:replace_climate": "Replace climate", + "lithostitched:modifier_type.lithostitched:replace_effects": "Replace effects", + "lithostitched:modifier_predicate_type.lithostitched:all_of": "All of", + "lithostitched:modifier_predicate_type.lithostitched:any_of": "Any of", + "lithostitched:modifier_predicate_type.lithostitched:mod_loaded": "Mod loaded", + "lithostitched:modifier_predicate_type.lithostitched:not": "Not", + "lithostitched:modifier_predicate_type.lithostitched:true": "True", "obsidian:item.information": "Item Information", "obsidian:item_information.rarity": "Rarity", @@ -115,5 +131,8 @@ "obsidian:block.display.model": "Model", "obsidian:block.display.item_model": "Item Model", "obsidian:block.display.block_model": "Block Model", - "obsidian:block.display.lore": "Lore" + "obsidian:block.display.lore": "Lore", + + "rule_test.blocks": "Blocks", + "rule_test.fluid": "Fluid" } diff --git a/src/app/schema/renderHtml.tsx b/src/app/schema/renderHtml.tsx index 162f541d..aa986b3c 100644 --- a/src/app/schema/renderHtml.tsx +++ b/src/app/schema/renderHtml.tsx @@ -15,7 +15,7 @@ import type { BlockStateRegistry, VersionId } from '../services/index.js' import { CachedDecorator, CachedFeature } from '../services/index.js' import { ModelWrapper } from './ModelWrapper.js' -const selectRegistries = ['loot_table.type', 'loot_entry.type', 'function.function', 'condition.condition', 'criterion.trigger', 'recipe.type', 'dimension.generator.type', 'dimension.generator.biome_source.type', 'dimension.generator.biome_source.preset', 'carver.type', 'feature.type', 'decorator.type', 'feature.tree.minimum_size.type', 'block_state_provider.type', 'trunk_placer.type', 'foliage_placer.type', 'tree_decorator.type', 'int_provider.type', 'float_provider.type', 'height_provider.type', 'structure_feature.type', 'surface_builder.type', 'processor.processor_type', 'rule_test.predicate_type', 'pos_rule_test.predicate_type', 'template_element.element_type', 'block_placer.type', 'block_predicate.type', 'material_rule.type', 'material_condition.type', 'structure_placement.type', 'density_function.type', 'root_placer.type', 'entity.type_specific.cat.variant', 'entity.type_specific.frog.variant', 'rule_block_entity_modifier.type', 'pool_alias_binding.type'] +const selectRegistries = ['loot_table.type', 'loot_entry.type', 'function.function', 'condition.condition', 'criterion.trigger', 'recipe.type', 'dimension.generator.type', 'dimension.generator.biome_source.type', 'dimension.generator.biome_source.preset', 'carver.type', 'feature.type', 'decorator.type', 'feature.tree.minimum_size.type', 'block_state_provider.type', 'trunk_placer.type', 'foliage_placer.type', 'tree_decorator.type', 'int_provider.type', 'float_provider.type', 'height_provider.type', 'structure_feature.type', 'surface_builder.type', 'processor.processor_type', 'rule_test.predicate_type', 'pos_rule_test.predicate_type', 'template_element.element_type', 'block_placer.type', 'block_predicate.type', 'material_rule.type', 'material_condition.type', 'structure_placement.type', 'density_function.type', 'root_placer.type', 'entity.type_specific.cat.variant', 'entity.type_specific.frog.variant', 'rule_block_entity_modifier.type', 'pool_alias_binding.type', 'lithostitched.worldgen_modifier.type', 'lithostitched.modifier_predicate.type'] const hiddenFields = ['number_provider.type', 'score_provider.type', 'nbt_provider.type', 'int_provider.type', 'float_provider.type', 'height_provider.type'] const flattenedFields = ['feature.config', 'decorator.config', 'int_provider.value', 'float_provider.value', 'block_state_provider.simple_state_provider.state', 'block_state_provider.rotated_block_provider.state', 'block_state_provider.weighted_state_provider.entries.entry.data', 'rule_test.block_state', 'structure_feature.config', 'surface_builder.config', 'template_pool.elements.entry.element', 'decorator.block_survives_filter.state', 'material_rule.block.result_state'] const inlineFields = ['loot_entry.type', 'function.function', 'condition.condition', 'criterion.trigger', 'dimension.generator.type', 'dimension.generator.biome_source.type', 'feature.type', 'decorator.type', 'block_state_provider.type', 'feature.tree.minimum_size.type', 'trunk_placer.type', 'foliage_placer.type', 'tree_decorator.type', 'block_placer.type', 'rule_test.predicate_type', 'processor.processor_type', 'template_element.element_type', 'nbt_operation.op', 'number_provider.value', 'score_provider.name', 'score_provider.target', 'nbt_provider.source', 'nbt_provider.target', 'generator_biome.biome', 'block_predicate.type', 'material_rule.type', 'material_condition.type', 'density_function.type', 'root_placer.type', 'entity.type_specific.type', 'glyph_provider.type', 'sprite_source.type', 'rule_block_entity_modifier.type', 'immersive_weathering.area_condition.type', 'immersive_weathering.block_growth.growth_for_face.entry.direction', 'immersive_weathering.position_test.predicate_type', 'pool_alias_binding.type'] diff --git a/src/config.json b/src/config.json index 5d4a8118..82e459ce 100644 --- a/src/config.json +++ b/src/config.json @@ -538,6 +538,14 @@ "schema": "immersive_weathering:block_growth", "minVersion": "1.18.2" }, + { + "id": "lithostitched.worldgen_modifier", + "url": "lithostitched/worldgen-modifier", + "path": "lithostitched/worldgen_modifier", + "tags": ["partners"], + "schema": "lithostitched:worldgen_modifier", + "minVersion": "1.20.2" + }, { "id": "obsidian.item", "url": "obsidian/item", diff --git a/src/locales/en.json b/src/locales/en.json index 8b2bbd36..466a67aa 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -175,6 +175,8 @@ "partner.obsidian": "Obsidian", "generator.obsidian.item": "Obsidian Item", "generator.obsidian.block": "Obsidian Block", + "partner.lithostitched": "Lithostitched", + "generator.lithostitched.worldgen_modifier": "Worldgen Modifier", "presets": "Presets", "preview": "Visualize", "preview.auto_scroll": "Auto scroll",