Events
KubeJS TFC adds several JS events for use in scripts
-
Placed Item Models –
client_scripts -
Animal Product –
server_scripts -
Collapse –
server_scripts -
Create Chunk Data Provider –
server_scripts -
Douse Fire –
server_scripts -
Limit Container –
server_scripts -
Log –
server_scripts -
Prospect –
server_scripts -
Select Climate Model –
server_scripts -
Start Fire –
server_scripts -
Custom Nutrition –
startup_scripts -
Default World Settings –
startup_scripts -
Fauna Spawns –
startup_scripts -
Interactions –
startup_scripts -
Prospect Representatives –
startup_scripts
Placed Item Models
Listener: TFCEvents.placeItemModels(...)
Script Type: client_scripts
TFC adds the ability to place items in-world via a keybind. By default the item model is displayed, but the ability to override the models used by specific items does exist. This event allows for scripts to define such overrides
Methods
: Register the given model to the item with the.cutout(item: Item, model: ResourceLocation): voidcutoutrender type
: Register the given model to the item with the.translucent(item: Item, model: ResourceLocation): voidtranslucentrender type
Example
TFCEvents.placeItemModels(event => {
event.cutout('minecraft:iron_door', 'minecraft:block/glass')
})
Animal Product
Listener: TFCEvents.animalProduct(...)
Script Type: server_scripts
This event is fired whenever an animal product is produced: a sheep is sheared, a cow is milked, etc. Cancelling will prevent the default behavior, which is controlled by each entity’s implementation. This event does not control if an entity can provide products, only for modifying/blocking them
The product of this event my be either an ItemStack of a FluidStack, not both. Attempting to change the product from an item to fluid or vice-versa will void all products
Methods
: Get the player retrieving the product.getPlayer(): Player
: Get the animal the product is from.getAnimal(): Entity
: Get the level of the animal.getLevel(): Level
: Get the position of the animal.getPos(): BlockPos
: Get the animal properties of the animal.getAnimalProperties(): TFCAnimalProperties
: Get the item used by the player to get the product.getTool(): ItemStack
: Get the item product, may be empty if the original product was a fluid.getItemProduct(): ItemStack
: Get the fluid product, may be empty of the original product was an item.getFluidProduct(): FluidStack
: If the original product was an item.isItemProduct(): boolean
: Set the item product.setItemProduct(item: ItemStack): void
: Set the fluid product.setFluidProduct(fluid: FluidStack): void
: Get the amount of ‘wear’ the animal will take from the event.getUses(): int
: Set the amount of ‘wear’ the animal will take from the event.setUses(uses: int): void
: Prevent any product from being given to the player.cancel(): void
Example
TFCEvents.animalProduct(event => {
if (event.getAnimalProperties().getGeneticSize() < 10) {
event.cancel()
} else if (event.isItemProduct()) {
event.setItemProduct('minecraft:dirt')
}
})
Collapse
Listener: TFCEvents.collapse(...)
Script Type: server_scripts
This event fires whenever a collapse, real or fake, occurs
Methods
: Get the origin position of the collapse.getCenterPos(): BlockPos
: Get the level the collapse occurred in.getLevel(): Level
: Get the square of the maximum distance from the center that blocks may collapse. Will be.getRadiusSquared(): number0if the collapse is fake
: Get the additional positions where a block will collapse or, if the collapse is fake, particles will spawn.getSecondaryPositions(): List<BlockPos>
: If the collapse is fake.isFake(): boolean
Example
TFCEvents.collapse(event => {
event.getSecondaryPositions().forEach(pos => {
event.getLevel().playSound(null, pos, 'minecraft:block.wood.break', 'blocks', 1, 1)
})
})
Create Chunk Data Provider
Listener: TFCEvents.createChunkDataProvider(...)
Target Type: String
Script Type: server_scripts
When used with a specific chunk generator type, this event allows for custom generation of TFC’s ChunkData, permitting fauna definitions; climate placement modifiers; TFC’s climate based structure modifier; and many other features which are reliant on the chunk generator being TFC-like to function properly with chunk generator’s other than TFC’s
Chunk Generator
Due to how TFC’s chunk data works, this functionality is inherently tied to a ChunkGenerator. KubeJS TFC adds a new generator type, kubejs_tfc:wrapped, which will wrap any arbitrary chunk generator an imitate its function while providing TFC’s additional values
In its json definition, the generator has the following fields
typemust bekubejs_tfc:wrappedevent_key: The key for which the event is fired for. A stringsettings: The same astfc_settingsin TFC’s chunk generator type. These values are available during the event via.getSettings()generator: A chunk generator
Example
{
"type": "kubejs_tfc:wrapped",
"event_key": "nether",
"generator": {
"type": "minecraft:noise",
"biome_source": {
"type": "minecraft:multi_noise",
"preset": "minecraft:nether"
},
"settings": "minecraft:nether"
},
"settings": {
"flat_bedrock": true,
"spawn_distance": 10000,
"spawn_center_x": 0,
"spawn_center_z": 0,
"temperature_scale": 20000,
"rainfall_scale": 1,
"continentalness": 0.5,
"finite_continents": false,
"grass_density": 0,
"rock_layer_settings": {
"rocks": {
"nether": {
"raw": "minecraft:netherack",
"hardended": "minecraft:basalt",
"gravel": "minecraft:gravel",
"cobble": "minecraft:blackstone",
"sand": "minecraft:soul_sand",
"sandstone": "minecraft:soul_soil"
}
},
"bottom": [ "nether" ],
"layers": [
{
"id": "nether",
"layers": {
"nether": "bottom"
}
}
],
"ocean_bottom": [ "nether" ],
"volcanic": [ "nether" ],
"land": [ "nether" ],
"uplift": [ "nether" ]
}
}
}
Rock Surface Rule Source
In addition, a custom surface rule source that uses the blocks of the RockSettings, as provided by the rocks callback of the provider, is available. This rule source only works with the kubejs_tfc:wrapped generator wrapping a minecraft:noise1 chunk generator
In its json, the rule source has the following fields
typemust bekubejs_tfc:rockfallback_state: A lenient block state. Used when theRockSettingsat a position could not be found or the chunk generator is not compatible with this rule sourcerock_block: A string, one ofraw,hardened,gravel,cobble,sand, orsandstone. Specified which block from theRockSettingsto use. Optional, defaults toraw
Example
{
"type": "kubejs_tfc:rock",
"rock_block": "sandstone",
"fallback_state": "minecraft:sandstone"
}
Methods
: Get the world seed.getWorldSeed(): int
: Get the.getNormalNoise(id: ResourceKey<NormalNoise$NoiseParameters>): NormalNoiseNormalNoisedefined by the noise parameters with the given id
: Get a thread-unsafe.stableRandomSource(): RandomSourceRandomSourceseeded by the world seed
: Get a thread-unsafe.unstableRandomSource(): RandomSourceRandomSourcewith an arbitrary seed
: Get the TFC.getSettings(): SettingsSettingsof the chunk generator
: Set the calculation for the information required to promote a chunk’s.partial(gen: Consumer<ChunkData>): voidChunkDatatopartial.ChunkData.generatePartial(...)should be called here.ChunkData.generateFull(...)may be called here, however chunk information is not available. If a chunk is not promoted topartial, the provider will automatically do so with0values
: Set the calculation for the information required to promote a chunk’s.full(gen: BiConsumer<ChunkData, ChunkAccess>): voidChunkDatafrompartialtofull.ChunkData.generateFull(...)should be called here. If a chunk is not promoted tofull, the provider will automatically do so with values derived from theocean_floor_wgheightmap. Accepts a callback with two parametersdata: ChunkData: TheChunkDatabeing promoted tofullchunk: ChunkAcess: The chunk the data is being generated for. Theocean_floor_wgandworld_surface_wgheightmaps are available
: Set the calculation for the.erosionalAquifer(maker: Function<ChunkAccess, Aquifer>): voidAquiferof a given chunk. The aquifer is used by TFC’s erosion feature to place subterranean fluids. If not set, defaults to an aquifer that places air at at y -2^31. Accepts a callback with the paramschunk: ChunkAccess: The chunk the aquifer is being generated forreturn: Aquifer: AnAquifer. SeeTFCAquiferfor TFC’s implementation
: Set the calculation for the.rocks(rocksGetter: RocksGetter): voidRockSettingsat a position. Used by several configured feature types and the rock surface rule source to determine what blocks to place. If not set, ornullis returned in the callback, aRockSettingsmade entirely of air is used. Accepts a callback with the paramsx: int: The x coordinatey: int: The y coordinatez: int: The z coordinatesurfaceY: int: The surface elevation of the block column, as determined by the surface elevations used to promote the chunk tofullcache: @Nullable ChunkRockDataCache: A potentiallynullChunkRockDataCache. Holds per-layer height and skew valuesrockLayers: RockLayerSettings: TheRockLayerSettingsdefined in the chunk generator’ssettingsobject. This has a method,.sampleAtLayer(pointRock: int, layerN: int), which returns aRockSettings. The parameters arepointRock: int: A 32-bit signed integer. The top 30 bits are used as a seed for a random number generator used to pick from the layer’s mappings for the next layer whenlayerNis greater than0. The bottom two bits are used to select which primary rock type is used at the 0th layer0b00: Ocean layer0b01: Volcanic layer0b10: Land layer0b11: Uplift layer
layerN: int: How many times to iterate to the layer’s next layer as described by the layer’s mapping. Accepts any non-negative number; thebottompseudo-layer points towards itself
return: RockSettings: ARockSettingsdescribing the rock at the position. Ideally retrieved fromrockLayers
-
Or any generator type which extends
NoisebasedChunkGeneratorand overrides.buildSurface(ChunkAccess,WorldGenerationContext,RandomState,StructureManager,BiomeManager,Registry<Biome>,Blender)↩
Example
TFCEvents.createChunkDataProvider('nether', event => {
// Use a LayeredArea for the rocks as noises can be slow when used with the rock rule source
const randomSource = event.stableRandomSource()
// This rock layer mirrors how TFC does its own rock layer
const rockLayer = TFC.worldgen.uniformLayeredArea(randomSource.nextLong())
for (let i = 0 ; i < 3 ; i++) {
rockLayer
.zoom(true, randomSource.nextLong())
.smooth(randomSource.nextLong())
}
for (let i = 0 ; i < 6 ; i++) {
rockLayer.zoom(true, randomSource.nextLong())
}
rockLayer
.smooth(randomSource.nextLong())
.zoom(true, randomSource.nextLong())
.smooth(randomSource.nextLong())
// Since The nether does not have rain, pre-create an empty float layer to use
const rain = TFC.worldgen.lerpFloatLayer(0, 0, 0, 0)
const tempLayer = TFC.noise.openSimplex2D(event.getWorldSeed() + 7545452354354)
.spread(0.2)
.octaves(3)
scaled(95, 140)
const forestLayer = TFC.noise.openSimplex2D9event.getWorldSeed() + 14694769526)
.spread(0.8)
.terraces(9)
.affine(6, 12)
.scaled(6, 18, 0, 28)
const rockLayerHeightNoise = TFC.noise.openSimplex2D(event.getWorldSeed() + 6315343547)
.octaves(6)
.scaled(12, 34)
.spread(0.009)
// Precompute the aquifer heights as a constant since this is the nether
const aquifer = []
var i = 0
while (1 < 16) {
aquifer.push(0)
i++
}
event.partial(data => {
let { pos } = data
let { minBlockX: X, minBlockZ: z } = pos
var temp = tempLayer.overChunk(pos)
data.generatePartial(
rain,
rain,
rain,
temp,
forestLayer.noise(x, z) // Kube accepts ordinal numbers for enum constants
)
})
event.full((data, chunk) => {
var heights = []
// In the nether this will always return 127, but this is
// included as a demonstration of using height maps and
// properly indexing the height values within the array
for (let x = 0 ; x < 16 ; x++) {
for (let z = 0 ; z < 16 ; z++) {
var height = chunk.getHeight('ocean_floor_wg', x, z)
heights[x + 16 * z] = height
}
}
data.generateFull(heights, aquifer)
})
event.rocks((x, y, z, surfaceY, cache, rockLayers) => {
var layer = 0
var layerHeight = 0
var deltaY = surfaceY - y
do {
// A simplified version of what TFC does for its layer depth
// Of note is the lack of skewing for either the rock
// layer or the heights and the non-use of the cache
layerHeight = rockLayerHeightNoise.noise(x >> 5, z >> 5)
if (deltaY <= layerHeight) {
break
}
deltaY -= layerHeight
layer++
} while (deltaY > 0)
return rockLayer.sampleAtLayer(rockLayer.getAt(x, z), layer)
})
})
Douse Fire
Listener: TFCEvents.douseFire(...)
Script Type: server_scripts
This event fires whenever a block is extinguished via the shovel_douse item ability or a thrown bottle or water lands. A single dousing action may affect multiple blocks, in such case this event will fire once per block within the dousing bounds
Methods
: Get the level where the dousing is happening.getLevel(): Level
: Get the position being doused.getPos(): BlockPos
: Get the state at the doused position.getState(): BlockState
: The full bounds of the dousing action.getBounds(): AABB
: Get the player performing the dousing action, if available.getPlayer(): @Nullable Player
: Cancel the dousing action at the position.cancel(): void
Example
TFCEvents.douseFire(event => {
if (event.getState().hasTag('kubejs:remove_on_douse')) {
event.getLevel().removeBlock(event.getPos(), false)
event.cancel()
}
})
Limit Container
Listener: TFCEvents.limitContainer(...)
Target Type: ResourceKey<MenuType<?>>
Script Type: server_scripts
TFC has an item size feature which it uses, in its own containers, to limit what items can enter. Via this event, KubeJS TFC allows for this behavior to be replicated with arbitrary containers, with some limitations
- It will only apply to containers with a registered
MenuType<?> - It only applies upon a plyer interaction
- It only applies upon closing and opening the container screen, not any intermediate actions
The basic idea and functionality of the event is based on Oversized Item In Storage Area, a 1.12 addon that did similar
Upon the player opening/closing a container handled by this event, any items that are
- in the limited slots
- are not within the size limits
will be removed from the container and spawned around the player in-world
Methods
: Limits the entire container to the specified size, requiring any items in it to be smaller than the provided size..limit(size: Size, allowsEqual?: boolean): voidallowsEqualdetermines if asizeofsmallwill permit items of sizesmallto remain in the container, defaults totrue
: Limits the specified slot index range to the specified size, requiring any items in it to be smaller than the provided size..limit(size: Size, min: int, max: int, allowsEqual?: boolean): voidallowsEqualdetermines if asizeofsmallpermits items of sizesmallto remain in the container, defaults totrue
: Limits the entire container to the specified size, requiring any items in it to be larger than the provided size..lowerLimit(size: Size, allowsEqual?: boolean): voidallowsEqualdetermines if asizeofsmallwill permit items with a size ofsmallto remain in the container, defaults totrue
: Limits the specified slot index range to the specified size, requiring any items in it to be larger than the provided size..lowerLimit(size: Size, min: int, max: int, allowsEqual?: boolean): voidallowsEqualdetermines if asizeofsmallwill permit items with a size ofsmallto remain in the container, defaults totrue
Example
TFCEvents.limitContainer('minecraft:generic_9x3', event => {
event.limit('small', 0, 9)
event.limit('large', 18, 27)
event.lowerLimit('very_small', false)
})
Log
Listener: TFCEvents.log(...)
Script Type: server_scripts
This event fires whenever a natural log block is broken, prompting the tree to be felled
Methods
: Get the level the logging occurred in.getLevel(): Level
: Get the axe item use.getAxe(): ItemStack
: Get the position where a log block was broken.getPos(): BlockPos
: Get the block that was broken.getState(): BlockState
: Prevent the entire tree from being felled, only the initial block will be broken.cancel(): void
Example
TFCEvents.log(event => {
if (event.getPos().getY() > 80) {
event.cancel()
}
})
Prospect
Listener: TFCEvents.prospect(...)
Script Type: server_scripts
This event fires whenever a player uses a Prospector’s Pick
Methods
: Get the player prospecting.getPlayer(): Player
: Get the prospecting result, will be one of.getProspectResult(): ProspectResultvery_large,large,medium,small,traces,found, ornothing
: Get the block found by prospecting or, if the result is.getBlock(): Blocknothing, the block prospected
Example
TFCEvents.prospect(event => {
if (event.getBlock().hasTag('kubejs:super_special_ores')) {
event.getPlayer().notify('Congrats!', 'You found some special ore. Enjoy!')
}
})
Select Climate Model
Listener: TFCEvents.selectClimateModel(...)
Script Type: server_scripts
This event fires during world loading and is used to choose which implementation of climate model a level should use
Methods
: Get the level the model is being chosen for.getLevel(): ServerLevel
: Get dimension id of the level.dimensionId(): ResourceLocation
: Get the TFC.getWorldSettings(): @Nullable SettingsSettingsof the world if it has a TFc-like generator, elsenull
: Get the model that will currently be applied to the level.getModel(): ClimateModel
: Create a climate model based on a climate model type registered through scripts.kubeModel(id: ResourceLocation, hemisphereScale: number, supportsRain: boolean): @Nullable ClimateModelid: ResourceLocation: The id of the registered climate model typehemisphereScale: number: The hemisphere scale of the model to createsupportsRain: boolean: If the model should support rain
: Create a climate model based on a climate model type registered through scripts with a hemisphere scale of.kubeModel(id: ResourceLocation): @Nullable ClimateModel20000that supports rain
: Set the model to apply to the level.setModel(model: ClimateModel): void
Example
TFCEvents.selectClimateModel(event => {
if (event.dimensionId() == 'minecraft:the_nether') {
let model = event.kubeModel('kubejs:hell', 10000, false)
event.setModel(model)
}
})
Start Fire
Listener: TFCEvents.startFire(...)
Script Type: server_scripts
This event is fired whenever a block is lit on fire and can be cancelled to handle lighting of an external device or source
Methods
: Get the level the fire was started in.getLevel(): Level
: Get the position being ignited.getPos(): BlockPos
: Gets the block face clicked to ignite the block.getTargetedFace(): Direction
: Get the player that started the fire, if present.getPlayer(): @Nullable Player
: Get the item used to ignite the fire.getItem(): ItemStack
: If the fire is considered strong, and will place a fire block. If the event is strong and is cancelled a fire block will not be placed but TFC’s.isStrong(): booleanLITadvancement trigger will still play
: Cancel the ignition, exact behavior depends on block.cancel(): void
Example
TFCEvents.startFire(event => {
if (event.isStrong()) {
event.getPlayer().notify(
Text.warn('Arsonist!'),
Text.of('So you like to play with fire, eh?')
)
}
})
Custom Nutrition
Listener: TFCEvents.customNutrition(...)
Script Type: startup_scripts
This event fires whenever a player joins the world on both the client and server side so that their nutrition calculator may be changed
Methods
: Get the player the nutrition is for.getPlayer(): Player
: Get a.classForJavaAdapter(): ObjectINutritionDataclass wrapper that can be used withJavaAdapterto create new instances
: Get the current nutrition factory for the player. Has a single method,getFactory(): BiFunction<number, number, T extends INutritionData>.create(defaultNutritionValue: number, defaultDairyNutritionValue: number): T extends INutritionData
: Set the nutrition factory for the player. Accepts a callback with the params.setFactory(factory: BiFunction<number, number, INutritionData>)defaultNutritionValue: number: The default value for the non-dairy nutrientsdefaultDairyNutritionValue: number: The default value for the dairy nutrientreturn: INutritionData: The nutrition data, can be made usingJavaAdapter. Has the following methods that must be implemented.getAverageNutrition(): number: Get the average nutrition, in the range[0, 1], of the player. used to calculate the player’s health.getNutrient(nutrient: Nutrient): number: Get the value, in the range[0, 1]of the requested nutrient.getNutrients(): number[5]: Get the values, in the range[0, 1]of the player’s nutrients. Should be in the ordergrain,fruit,vegetables,protein,dairy.setHungerAndUpdate(hunger: int): void: Set the player’s current hunger value, in the range[0, 20], where0is an empty food bar. This may update the player’s nutrition.setHunger(hunger: int): void: Set the player’s current hunger value, in the range[0, 20], where0is an empty food bar. This must not update the player’s nutrition.onClientUpdate(nutrients: number[5]): void: Set the nutrient data, on the client side, from a packet.addNutrients(data: FoodData, currentHunger: int): void: Apply nutrients of a food to the player.writeToNbt(): Tag: Serialize any relevant data for computing nutrition to an NBT tag.readFromNbt(nbt: @Nullable Tag): void: Read any relevant data for computing nutrition from an NBT tag, the data serialized in.writeToNbt()`{:.language-kube-21}
Example
TFCEvents.customNutrition(event => {
event.setFactory((defNutrient, defDairy) => {
let avgNutrition = defNutrient
let nutrients = [
defNutrient,
defNutrient,
defNutrient,
defNutrient,
defDairy
]
// Do as you wish...
function applyHunger(hunger) { ... }
function updateNutrition() { ... }
function applyFood(foodData, currentHunger) { ... }
return JavaAdapter(event.classForJavaAdapter(), {
getAverageNutrition: function () => avgNutrition,
getNutrient: function (nutrient) => nutrients[nutrient.ordinal()],
getNutrients: function () => nutrients,
setHungerAndUpdate: function (hunger) => {
applyHunger(hunger)
updateNutrition()
},
setHunger: applyHunger,
onClientUpdate: function (serverNutrients) => nutrients = serverNutrients,
addNutrients: applyFood,
writeToNbt: function () => { ... },
readFromNbt: function(nbt) => { ... }
})
})
})
Default World Settings
Listener: TFCEvents.defaultWorldSettings(...)
Script Type: startup_scripts
Allows for editing the default values of the TFC chunk generator at world creation, including editing the rock layers
Methods
: Set if the world should have flat bedrock, defaults to.flatBedrock(flat?: boolean): voidfalse. Calling without any arguments sets totrue
: If, with the current settings, the world will have flat bedrock.getFlatBedrock(): boolean
: Set the maximum distance from the spawn center players may spawn.setSpawnDistance(distance: int): void
: Get, with the current settings, the maximum distance from the spawn center players may spawn.getSpawnDistance(): int
: Set the x-coordinate of the spawn center.setSpawnCenterX(x: int): void
: Get, with the current settings, the x-coordinate of the spawn center.getSpawnCenterX(): int
: Set the z-coordinate of the spawn center.setSpawnCenterZ(z: int): void
: Get, with the current settings, the z-coordinate of the spawn center.getSpawnCenterZ(): int
: Set the spawn center position.setSpawnCenter(x: int, z: int): void
: Set the temperature scale, the distance from the polar to equatorial region, of the world.setTemperatureScale(scale: int): void
: Get, with the current settings, the temperature scale.getTemperatureScale(): int
: Set the temperature constant of the world, the base temperature to use if the temperature scale is.setTemperatureConstant(constant: number): void0
: Get, with the current settings, the temperature constant.getTemperatureConstant(): number
: Set the rainfall scale, the distance from peak to peak, of the world.setRainfallScale(scale: int): void
: Get, with the current settings, the rainfall scale.getRainfallScale(): int
: Set the rainfall constant of the world, the base rainfall to use if the rainfall scale is.setRainfallConstant(constant: number): void0
: Get, with the current settings, the rainfall constant.getRainfallConstant(): number
: Set the portion of the world that is land instead of water. Defaults to.setContinentalNess(continentalness: number): void0.5
: Get, with the current settings, the continentalness of the world.getContinentalness(): number
: Set the grass density of the world, defaults to.setGrassDensity(density: number): void0.5
: Get, with the current settings, the grass density of the world.getGrassDensity(): number
: Set if the world should only generate a finite number of continents, defaults to.finiteContinents(finite?: boolean): voidfalse. Calling without any arguments sets totrue
: If, with the current settings, the world should only generate a finite number of continents.getFiniteContinents(): boolean
: Add the given.addRock(name: String, rock: RockSettings, bottom: boolean): voidrockto the generator’s pool of available rocksname: String: The name the rock can be referenced byrock: RockSettings: TheRockSettingsto add, can be created as a map of parameters to valuesraw: Block: The raw rock blockhardened: Block: The hardened rock blockgravel: Block: The gravel blockcobble: Block: The cobble blocksand: Block: The sand blocksandstone: Block: The sandstone blockspike?: Block: The spike block. Optionalloose?: Block: The loose pebble block. OptionalmossyLoose?: Block: The mossy loose pebble block. Optionalkarst?: boolean: If the rock has karst surface rocks. Optional, defaults tofalsemafic?: boolean: If the rock is considered mafic. Optional, defaults tofalse
bottom: boolean: If therockshould be added to thebottompseudo-layer
: Get the named.getRock(name: String): @Nullable RockSettingsRockSettings
: Get a collection of the names of all rocks in the generator’s pool of available rocks.getRockNames(): Set<String>
: Remove the given rock from the generator.removeRock(String name): void
: Add the given rock to the.addToBottom(name: String): voidbottompseudo-layer
: Remove the given rock from the.removeFromBottom(name: String): voidbottompseudo layer
: Define a new rock layer.defineLayer(id: String, rockMap: Map<String, String>): voidid: String: The id of the layerrockMap: Map<String, String>: A map of rock names to layer ids, associates a rock with the layer that will be generate below it
: Remove the given layer from the generator.removeLayer(id: String): void
: Get, with the current settings, a collection of the ids of all layers in the generator.getLayerIds(): List<String>
: Removes all rocks and layer from the generator.cleanSlate(): void
: Add the given layer to the.addVolcanicLayer(id: String): voidvolcaniclayer type
: remove the given layer from the.removeVolcanicLayer(id: String): voidvolcaniclayer type
: Get, with the current settings, the layers in the.getVolcanicLayers(): List<String>volcaniclayer type
: Add the given layer to the.addOceanFloorLayer(id: String): voidocean_floorlayer type
: remove the given layer from the.removeOceanFloorLayer(id: String): voidocean_floorlayer type
: Get, with the current settings, the layers in the.getOceanFloorLayers(): List<String>ocean_floorlayer type
: Add the given layer to the.addLandLayer(id: String): voidlandlayer type
: remove the given layer from the.removeLandLayer(id: String): voidlandlayer type
: Get, with the current settings, the layers in the.getLandLayers(): List<String>landlayer type
: Add the given layer to the.addUpliftLayer(id: String): voidupliftlayer type
: remove the given layer from the.removeUpliftLayer(id: String): voidupliftlayer type
: Get, with the current settings, the layers in the.getUpliftLayers(): List<String>upliftlayer type
Example
TFCEvents.defaultWorldSettings(event => {
event.finiteContinents()
event.flatBedrock()
event.setTemperatureScale(5000)
event.setRainfallScale(7500)
event.addRock('vanilla', {
raw: 'minecraft:stone'
hardened: 'minecraft:deepslate'
gravel: 'minecraft:gravel'
cobble: 'minecraft:cobblestone'
sand: 'minecraft:sand'
sandstone: 'minecraft:sandstone'
mafic: true
}, false)
event.defineLayer('mc_1', {
vanilla: 'bottom'
granite: 'diorite'
})
event.defineLayer('mc_2', {
vanilla: 'mc_1'
diorite: 'mc_1'
})
event.addUpliftLayer('mc_2')
event.addUpliftLayer('mc_1')
event.addVolcanicLayer('mc_1')
})
Fauna Spawns
Listener: TFCEvents.(...)
Script Type: startup_scripts
This event allows for registering a data driven spawn condition of entity types
This event functions by wrapping the relevant NeoForge event. Typically, this does not cause issues iff all other mods use the event like they’re supposed to. Unfortunately, multiloader mods (and Fabric mods via Connector) are unlikely to use NeoForge’s event (or the relevant Architectury event that delegates to Neo’s), leading to startup crashes when using this event for entities from said mods
In such cases, please open an issue on the mod’s page informing them of the proper way to register spawn placements. If the issue is with a Fabric mod loaded via Connector, a resolution to the issue is unlikely
: Get the no restrictions spawn placement type.noRestrictions(): SpawnPlacementType
: Get the in water spawn placement type.inWater(): SpawnPlacementType
: Get the in lava spawn placement type.inLava(): SpawnPlacementType
: Get the on ground spawn placement type.onGround(): SpawnPlacementType
: Registers a fauna-based spawn placement, completely replacing any existing spawn placements.replace(entityType: EntityType<? extends Entity>, suffix?: String, placementType: SpawnPlacementType, heightmap: Heightmap$Types): voidentityType: EntityType<? extends Entity>: The entity type to register the spawn forsuffix?: String: A string, a suffix to add to the id of the fauna data id. OptionalplacementType: SpawnPlacementType: A spawn placement type, a pre-filter on a position before the fauna predicateheightMap: Heightmap$Types: The heightmap to spawn the entity with
: Registers a fauna-based spawn placement, ANDing its requirements with any existing spawn placements.and(entityType: EntityType<? extends Entity>, suffix?: String)entityType: EntityType<? extends Entity>: The entity type to register the spawn forsuffix?: String: A string, a suffix to add to the id of the fauna data id. Optional
: Registers a fauna-based spawn placement, ORing its requirements with any existing spawn placements.or(entityType: EntityType<? extends Entity>, suffix?: String)entityType: EntityType<? extends Entity>: The entity type to register the spawn forsuffix?: String: A string, a suffix to add to the id of the fauna data id. Optional
Example
TFCEvents.(event => {
event.replace('minecraft:pig', event.onGround(), 'world_surface_wg')
event.and('minecraft:cow')
})
Interactions
Listener: TFCEvents.interactions(...)
Script Type: startup_scripts
TFC has a custom system for performing certain interactions with items, most notably knapping and ingot piling. This event exposes the ability to define custom interactions
Methods
: Register a block-item placement.registerBlockPlacement(item: Item, block: Block)
: Registers the given action for the specified target and ingredient.register(ingredient: Ingredient, target: InteractionManager$Target, action: OnItemUseAction): void
: Registers the given action for the specified target with a specific item filter than can be more flexible than ingredients.registerKeyed(filter: Predicate<ItemStack>, items: Supplier<Collection<Item>>, target: InteractionManager$Target, action: OnItemUseAction): voidfilter: Predicate<ItemStack>: Validation for if the action should run for a given stack, the item is guaranteed to be in the collection reified fromitemsitems: Supplier<Collection<Item>>: The items the action could possibly apply totarget: InteractionManager$Target: The player click target the action is valid foraction: OnItemUseAction: The action to perform upon item use
: Registers the given action for the specified target and item ability.registerAbility(ability: ItemAbility, target: InteractionManager$Target, action: OnItemUseAction)ability: ItemAbility: A NeoForgeItemAbility, the ability the item must have to perform this actiontarget: InteractionManager$Target: The player click target the action is valid foraction: OnItemUseAction: The action to perform upon item use
InteractionManager$Target
An enum with three values, air, blocks, and both. Determines if a player may be looking at air/a block to perform the action
OnItemUseAction
OnItemUseAction is a function interface which can be created via a callback with the params
stack: ItemStack: The stack the player usedcontext: UseOnContext: The context of the use eventreturn: InteractionResult: The result of using the item.passwill let vanilla/default behavior run afterwards
Example
TFCEvents.interactions(event => {
event.register('minecraft:diamond', 'blocks', (stack, ctx) => {
if (ctx.getLevel().getBlockState(ctx.getClickedPos()).hasTag('kubejs:can_accept_diamonds')) {
ctx.getLevel().setBlockAndUpdate(ctx.getClickedPos(), 'kubejs:diamond_encrusted_block')
return 'success'
}
return 'pass'
})
})
Prospect Representatives
Listener: TFCEvents.prospectRepresentatives(...)
Script Type: startup_scripts
TFC’s prospecting system allows multiple blocks to be treated as the same for the purposes of counting how many of a block were found. This event allows for the creation of such aliases
Method
: Register the representative of the given blocks.register(representative: Block, blocks...: Block[])representative: Block: The block to be reported/counted when prospectingblocks...: Block[]: The blocks to be represented by therepresentative
Example
TFCEvents.prospectRepresentatives(event => {
event.register('minecraft:sponge', 'minecraft:wet_sponge')
event.register('minecraft:terracotta', 'minecraft:white_terracotta', 'minecraft:red_terracotta', 'minecraft:lime_terracotta') // etc.
})