mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-10 20:35:02 +01:00
Merge branch 'mc1.19/dev' into mc1.20.1/dev
Conflicts: gradle.properties src/main/java/com/simibubi/create/Create.java src/main/java/com/simibubi/create/content/kinetics/fan/FanProcessing.java src/main/java/com/simibubi/create/content/trains/bogey/BogeyRenderer.java src/main/java/com/simibubi/create/foundation/mixin/client/FixNormalScalingMixin.java src/main/java/com/simibubi/create/infrastructure/gametest/tests/TestItems.java
This commit is contained in:
commit
78cf451f6d
88 changed files with 1094 additions and 1546 deletions
138
## Changes.md
138
## Changes.md
|
@ -1,138 +0,0 @@
|
||||||
## Additions
|
|
||||||
|
|
||||||
- Netherite Backtank
|
|
||||||
- Netherite Diving Helmet and Boots
|
|
||||||
- Contraption Controls
|
|
||||||
- Elevator Pulley
|
|
||||||
- Copycat Panels and Copycat Steps
|
|
||||||
- Block of Andesite Alloy
|
|
||||||
- Block of Industrial Iron
|
|
||||||
- Large Water Wheel
|
|
||||||
- Mechanical Roller
|
|
||||||
- Andesite, Brass and Copper Doors
|
|
||||||
- Andesite, Brass and Copper Bars
|
|
||||||
- Andesite, Brass and Copper Scaffolding
|
|
||||||
- Clipboard
|
|
||||||
- Mangrove Windows (1.19)
|
|
||||||
|
|
||||||
## Changes
|
|
||||||
|
|
||||||
- Overhauled models and textures of Andesite & Brass components (Kryppers)
|
|
||||||
- Reworked textures of colored blocks such as seats and sails (dani)
|
|
||||||
- New filter sprites (vectorwing)
|
|
||||||
- Valve handles can now be used to precisely turn mechanical bearings by a set angle
|
|
||||||
- Pulley ropes are now climbable
|
|
||||||
- Lowered hitbox of seats for improved traversability inside contraptions
|
|
||||||
- Improved safety for players standing on vertically moving contraptions
|
|
||||||
- Pulley contraptions will now make an effort to place remote players at y values sensible to the client
|
|
||||||
- Fixed seated entities on rotating contraptions not rendering at the correct location
|
|
||||||
- Deployers no longer fail to activate in chunks claimed or protected by the player that placed them
|
|
||||||
- Fixed couplings, schematics and in-world overlays not rendering correctly at coordinates far from the origin
|
|
||||||
- Fixed Bearings, Pistons, Pulleys and Gantries powered by a Sequenced Gearshift not moving precisely to its instructions at high speeds
|
|
||||||
- Minecart contraptions no longer visually jump to a location when stalled
|
|
||||||
- Mechanical bearings now snap to a rounded angle when stopped
|
|
||||||
- Contraption storage now accepts more chests and barrels from other mods
|
|
||||||
- Players can now open chests and barrels on assembled contraptions
|
|
||||||
- Mechanical Pumps no longer reverse direction based on kinetic input
|
|
||||||
- Fixed pipe connections pulling fluids with half the speed compared to a directly attached pump
|
|
||||||
- Substantially increased speed of visual flow propagation inside pipe networks
|
|
||||||
- Portable storage interfaces now stall for longer after an exchange has happened, and shorter otherwise
|
|
||||||
- Single train track blocks with slopes connected on either side will angle themselves to create a smoother ascend across both
|
|
||||||
- Multiple pulleys can now attach to contraptions in a synchronised group
|
|
||||||
- Display Boards now update text instantaneously at high input rpm
|
|
||||||
- Diving helmets now always grant aqua affinity
|
|
||||||
- Diving helmets can no longer be enchanted with aqua affinity
|
|
||||||
- Water wheel fins are no longer directional
|
|
||||||
- Water wheels now only have one speed level
|
|
||||||
- Water wheels can now take the appearance of any reasonably implemented wood type
|
|
||||||
- Added sided door control options to elevator contact and train station UI
|
|
||||||
- Liquid can no longer spread perpendicularly on top of water wheels
|
|
||||||
- Overhauled UX of scroll values and item filtering
|
|
||||||
- Filtered item extraction can now be configured to pull "up to x items" per operation
|
|
||||||
- Connected textures now use and apply the getAppearance() standard by Forge, allowing them to connect across other mods' facades, etc. (1.19)
|
|
||||||
- Boiler status now highlights information about water flow when insufficient
|
|
||||||
- The majority of in-world options no longer require a wrench
|
|
||||||
- Chutes can now be encased in Industrial Iron Blocks
|
|
||||||
- Chutes are now less prone to resetting shape when moved or rotated
|
|
||||||
- Moved metal block variants to Building Blocks tab
|
|
||||||
- Changed stonecutting ingredient of metal block variants from sheet to ingot
|
|
||||||
- Base stone blocks can now be stonecut back from their cut variants
|
|
||||||
- Fixed track placement allowing an s-bend between two sloped track pieces in specific arrangements
|
|
||||||
- Fixed funnels losing filters when changing between types
|
|
||||||
- New randomised textures for natural palette stone types (Kryppers)
|
|
||||||
- Readjusted palette stone generation to use taller layers
|
|
||||||
- World generation now places fewer stone type veins by default
|
|
||||||
- Fixed lava fans voiding items that have smoking & smelting recipes with different outputs
|
|
||||||
- Filter items now filter for their own item type if left empty
|
|
||||||
- Valve handles no longer create stress config entries for each dyed variant
|
|
||||||
- Place near initial angle mode on bearings now has a smaller interval considered 'near'
|
|
||||||
- Players can now take items from saws via right-click
|
|
||||||
- Item Drains now accept dropped items as input
|
|
||||||
- Train track placement overlay now explicitly mentions the ctrl key
|
|
||||||
- Fixed Mechanical Saws not rendering as animated when using rubidium
|
|
||||||
- Fixed a ui element of the Station Screen rendering behind the background
|
|
||||||
- Belts printed instantly or via cannon now retain the correct type of casing
|
|
||||||
- Scheduled trains no longer slow down for slight ascends/descents on a straight track
|
|
||||||
- Fixed saplings and other non-collidables sticking to chassis or super glue
|
|
||||||
- Encased Fluid Pipes no longer z-fight on open pipe faces
|
|
||||||
- Valve handles now turn twice as quickly
|
|
||||||
- Bearings no longer have the angle-indicating nook on their block
|
|
||||||
- Depot hitbox is now a simple cuboid
|
|
||||||
- Fixed belts encased with andesite briefly showing brass textures
|
|
||||||
- Fixed Filters and Attribute Filters not stacking with unmodified, equivalent stacks
|
|
||||||
- Fixed Attribute Filters saving the name tag preview item in their data
|
|
||||||
- Filters and Schedules can now be reset via crafting
|
|
||||||
- Renamed Sails to Windmill Sails
|
|
||||||
- Crushing gold ore now yields more experience nuggets
|
|
||||||
- Fixed valve pipes sometimes not rotating their indicator fully
|
|
||||||
- Horizontal, encased belts now render a support structure when solid blocks are above them
|
|
||||||
- Added placement assist for mechanical drills, saws and deployers
|
|
||||||
- Mechanical Belts can now be waterlogged
|
|
||||||
- Depots and Ejectors can now be Waterlogged
|
|
||||||
- Chutes and Funnels can now be Waterlogged
|
|
||||||
- Fixed upright mechanical saws only able to be oriented in two directions
|
|
||||||
- Deployers now have their filter slot on the side of the block
|
|
||||||
- Deployers can now be rotated by wrenching them near the edge of the front face
|
|
||||||
- Deployers now set filters on blocks only by targeting any location on a correct side
|
|
||||||
- Fixed Schematics loaded for deployer printing not rotating block entity contents
|
|
||||||
- Added tripwire to #movable_empty_collider
|
|
||||||
- Renamed Stockpile Switch to Threshold Switch
|
|
||||||
- Renamed Content Observer to Smart Observer
|
|
||||||
- Smart observer and threshold switch can now be oriented to face blocks above or below them
|
|
||||||
- Smart observer will now also emit redstone when the block in front of it matches its filter
|
|
||||||
- Fixed non-vanilla signs not accepted as valid display targets
|
|
||||||
- Brass tunnels with no distribution behaviour no longer show the mode switcher
|
|
||||||
- Used more contrasting colours for diode and tunnel value inputs
|
|
||||||
- Fixed crash when hose pulley cannot find reference fluid for infinite draining
|
|
||||||
- Clipboards can now be used to transfer settings between blocks
|
|
||||||
- Clipboards can now be used to manually write to Display Boards and Nixie Tubes
|
|
||||||
- Clipboards can now be used as Material Checklists in the Schematicannon
|
|
||||||
- Fixed and edited existing tooltips and ponder scenes to include behavioural changes in 0.5.1
|
|
||||||
- New ponder scenes for Smart Observer, Threshold Switch, Elevator Pulley, Contraption Controls and Mechanical Rollers
|
|
||||||
- Fixed ponder overlay text rendering with wonky pixels
|
|
||||||
- Added a ponder category for recently added/changed blocks
|
|
||||||
- Renamed Filter to List Filter
|
|
||||||
- Deployers can now apply filters to a Redstone link with less required precision
|
|
||||||
- Bezier track segments now render with a slight angle to reduce z-fighting
|
|
||||||
- Fixed offset shaft rotation on encased large cogwheels
|
|
||||||
- Fixed Smart Fluid Pipe not dropping filter when broken
|
|
||||||
- Placards and Creative Crates will no longer hold on to special nbt content (except potion data, damage, enchants) of the contained item when imported via Schematicannon
|
|
||||||
- Schematicannons can no longer print mobs
|
|
||||||
- Fixed item frames not requiring an exact nbt match for printed contents
|
|
||||||
- Players can now sneak while using exp nuggets to only consume one item at a time
|
|
||||||
- Minecart contraption items can no longer be placed in container items like toolboxes or shulkers (configurable)
|
|
||||||
- Implemented ComputerCraft interaction for Speed Controllers, Display Links, Speedometers, Stressometers, Sequenced Gearshifts and Train Stations (caelwarner)
|
|
||||||
- Hand crank no longer drains hunger when using the extendo grip (Xstoudi)
|
|
||||||
- Fixed Encased Chain Drives not reacting to block rotation and mirroring correctly
|
|
||||||
- Open Ended Pipes now correctly handle Builder's Tea (NerdsOfAFeather)
|
|
||||||
- Added Config entry for brass tunnel distribution cooldown (Walle123)
|
|
||||||
- API for custom bogey & track types (Rabbitminers, techno-sam)
|
|
||||||
- Fixed server crash caused by Gantry Contraptions assembling (Lucasmellof)
|
|
||||||
- Fix "Lighter than air" fluids displayed incorrectly in spouts (cakeGit)
|
|
||||||
- Added rotate and mirror methods to Fluid Pipes (xieve)
|
|
||||||
- Chocolate & Honey fluid fog distance is now configurable (radimous)
|
|
||||||
- Added a TrackGraph merge event (DaComputerNerd717)
|
|
||||||
- Fixed players dismounting when trains get assembled (Equinoxxe)
|
|
||||||
- Added GameTests (TropheusJ)
|
|
||||||
- Added armor tags (NerdsOfAFeather)
|
|
||||||
- Major updates now release as patch A
|
|
3
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
3
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
|
@ -49,6 +49,8 @@ body:
|
||||||
label: Mod Version
|
label: Mod Version
|
||||||
description: The version of the mod you were using when the bug occured
|
description: The version of the mod you were using when the bug occured
|
||||||
options:
|
options:
|
||||||
|
- "0.5.1d"
|
||||||
|
- "0.5.1c"
|
||||||
- "0.5.1b"
|
- "0.5.1b"
|
||||||
- "0.5.1a"
|
- "0.5.1a"
|
||||||
- "0.5.0i"
|
- "0.5.0i"
|
||||||
|
@ -114,6 +116,7 @@ body:
|
||||||
label: Minecraft Version
|
label: Minecraft Version
|
||||||
description: The version of Minecraft you were using when the bug occured
|
description: The version of Minecraft you were using when the bug occured
|
||||||
options:
|
options:
|
||||||
|
- "1.20.1"
|
||||||
- "1.19.2"
|
- "1.19.2"
|
||||||
- "1.18.2"
|
- "1.18.2"
|
||||||
- "1.18.1"
|
- "1.18.1"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<p align="center"><img src="https://i.imgur.com/SXaePW6.png" alt="Logo" width="200"></p>
|
<p align="center"><img src="https://i.imgur.com/SXaePW6.png" alt="Logo" width="200"></p>
|
||||||
<h1 align="center">Create <br>
|
<h1 align="center">Create <br>
|
||||||
<a href="https://www.patreon.com/simibubi"><img src="https://img.shields.io/badge/Supporters-110-ff5733" alt="Patreon"></a>
|
<a href="https://www.patreon.com/simibubi"><img src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dsimibubi%26type%3Dpatrons&style=flat&label=Supporters&color=ff5733" alt="Patreon"></a>
|
||||||
<a href="https://www.curseforge.com/minecraft/mc-mods/create/files"><img src="https://img.shields.io/badge/Available%20for-MC%201.14%20to%201.18-c70039" alt="Supported Versions"></a>
|
<a href="https://www.curseforge.com/minecraft/mc-mods/create/files"><img src="https://cf.way2muchnoise.eu/versions/328085(c70039).svg" alt="Supported Versions"></a>
|
||||||
<a href="https://github.com/Creators-of-Create/Create/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Creators-of-Create/Create?style=flat&color=900c3f" alt="License"></a>
|
<a href="https://github.com/Creators-of-Create/Create/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Creators-of-Create/Create?style=flat&color=900c3f" alt="License"></a>
|
||||||
<a href="https://discord.gg/hmaD7Se"><img src="https://img.shields.io/discord/620934202875183104?color=5865f2&label=Discord&style=flat" alt="Discord"></a>
|
<a href="https://discord.gg/hmaD7Se"><img src="https://img.shields.io/discord/620934202875183104?color=5865f2&label=Discord&style=flat" alt="Discord"></a>
|
||||||
<a href="https://www.curseforge.com/minecraft/mc-mods/create"><img src="http://cf.way2muchnoise.eu/328085.svg" alt="CF"></a>
|
<a href="https://www.curseforge.com/minecraft/mc-mods/create"><img src="http://cf.way2muchnoise.eu/328085.svg" alt="CF"></a>
|
||||||
|
|
|
@ -169,7 +169,7 @@ dependencies {
|
||||||
jarJar.ranged(it, '[MC1.19.3-1.1.10,)')
|
jarJar.ranged(it, '[MC1.19.3-1.1.10,)')
|
||||||
}
|
}
|
||||||
jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
|
jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") {
|
||||||
jarJar.ranged(it, '[0.6.9,0.6.10)')
|
jarJar.ranged(it, '[0.6.10,0.6.11)')
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")
|
implementation fg.deobf("com.tterrag.registrate:Registrate:${registrate_version}")
|
||||||
|
|
|
@ -4,7 +4,7 @@ org.gradle.jvmargs = -Xmx3G
|
||||||
org.gradle.daemon = false
|
org.gradle.daemon = false
|
||||||
|
|
||||||
# mod version info
|
# mod version info
|
||||||
mod_version = 0.5.1.d
|
mod_version = 0.5.1.e
|
||||||
artifact_minecraft_version = 1.20.1
|
artifact_minecraft_version = 1.20.1
|
||||||
|
|
||||||
minecraft_version = 1.20.1
|
minecraft_version = 1.20.1
|
||||||
|
@ -22,8 +22,8 @@ use_parchment = true
|
||||||
|
|
||||||
# dependency versions
|
# dependency versions
|
||||||
registrate_version = MC1.20-1.3.3
|
registrate_version = MC1.20-1.3.3
|
||||||
flywheel_minecraft_version = 1.20
|
flywheel_minecraft_version = 1.20.1
|
||||||
flywheel_version = 0.6.9-4
|
flywheel_version = 0.6.10-6
|
||||||
jei_minecraft_version = 1.20.1
|
jei_minecraft_version = 1.20.1
|
||||||
jei_version = 15.2.0.22
|
jei_version = 15.2.0.22
|
||||||
curios_minecraft_version = 1.20.1
|
curios_minecraft_version = 1.20.1
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
// 1.20.1 2023-08-24T21:57:44.7330415 Create's Recipe Serializer Tags
|
||||||
|
0d8718f7383761bc5d7bc45306ed266ebf25dc1d data/create/tags/recipe_serializer/automation_ignore.json
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"values": [
|
||||||
|
{
|
||||||
|
"id": "occultism:spirit_trade",
|
||||||
|
"required": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "occultism:ritual",
|
||||||
|
"required": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,12 +1,10 @@
|
||||||
package com.simibubi.create;
|
package com.simibubi.create;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.simibubi.create.compat.jei.ConversionRecipe;
|
import com.simibubi.create.compat.jei.ConversionRecipe;
|
||||||
import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe;
|
import com.simibubi.create.content.equipment.sandPaper.SandPaperPolishingRecipe;
|
||||||
import com.simibubi.create.content.equipment.toolbox.ToolboxDyeingRecipe;
|
import com.simibubi.create.content.equipment.toolbox.ToolboxDyeingRecipe;
|
||||||
|
@ -16,8 +14,8 @@ import com.simibubi.create.content.kinetics.crafter.MechanicalCraftingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.crusher.CrushingRecipe;
|
import com.simibubi.create.content.kinetics.crusher.CrushingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe;
|
import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe;
|
||||||
import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe;
|
import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe;
|
||||||
import com.simibubi.create.content.kinetics.fan.HauntingRecipe;
|
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.fan.SplashingRecipe;
|
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.millstone.MillingRecipe;
|
import com.simibubi.create.content.kinetics.millstone.MillingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.mixer.CompactingRecipe;
|
import com.simibubi.create.content.kinetics.mixer.CompactingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.mixer.MixingRecipe;
|
import com.simibubi.create.content.kinetics.mixer.MixingRecipe;
|
||||||
|
@ -29,7 +27,6 @@ import com.simibubi.create.content.processing.recipe.ProcessingRecipeSerializer;
|
||||||
import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipeSerializer;
|
import com.simibubi.create.content.processing.sequenced.SequencedAssemblyRecipeSerializer;
|
||||||
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
|
import com.simibubi.create.foundation.recipe.IRecipeTypeInfo;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
|
||||||
|
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
@ -127,12 +124,9 @@ public enum AllRecipeTypes implements IRecipeTypeInfo {
|
||||||
.getRecipeFor(getType(), inv, world);
|
.getRecipeFor(getType(), inv, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Set<ResourceLocation> RECIPE_DENY_SET =
|
|
||||||
ImmutableSet.of(new ResourceLocation("occultism", "spirit_trade"), new ResourceLocation("occultism", "ritual"));
|
|
||||||
|
|
||||||
public static boolean shouldIgnoreInAutomation(Recipe<?> recipe) {
|
public static boolean shouldIgnoreInAutomation(Recipe<?> recipe) {
|
||||||
RecipeSerializer<?> serializer = recipe.getSerializer();
|
RecipeSerializer<?> serializer = recipe.getSerializer();
|
||||||
if (serializer != null && RECIPE_DENY_SET.contains(RegisteredObjects.getKeyOrThrow(serializer)))
|
if (serializer != null && AllTags.AllRecipeSerializerTags.AUTOMATION_IGNORE.matches(serializer))
|
||||||
return true;
|
return true;
|
||||||
return recipe.getId()
|
return recipe.getId()
|
||||||
.getPath()
|
.getPath()
|
||||||
|
|
|
@ -20,6 +20,7 @@ import net.minecraft.world.entity.EntityType;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
import net.minecraft.world.item.Item;
|
import net.minecraft.world.item.Item;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.Fluid;
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
@ -317,10 +318,53 @@ public class AllTags {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum AllRecipeSerializerTags {
|
||||||
|
|
||||||
|
AUTOMATION_IGNORE,
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
|
public final TagKey<RecipeSerializer<?>> tag;
|
||||||
|
public final boolean alwaysDatagen;
|
||||||
|
|
||||||
|
AllRecipeSerializerTags() {
|
||||||
|
this(MOD);
|
||||||
|
}
|
||||||
|
|
||||||
|
AllRecipeSerializerTags(NameSpace namespace) {
|
||||||
|
this(namespace, namespace.optionalDefault, namespace.alwaysDatagenDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
AllRecipeSerializerTags(NameSpace namespace, String path) {
|
||||||
|
this(namespace, path, namespace.optionalDefault, namespace.alwaysDatagenDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
AllRecipeSerializerTags(NameSpace namespace, boolean optional, boolean alwaysDatagen) {
|
||||||
|
this(namespace, null, optional, alwaysDatagen);
|
||||||
|
}
|
||||||
|
|
||||||
|
AllRecipeSerializerTags(NameSpace namespace, String path, boolean optional, boolean alwaysDatagen) {
|
||||||
|
ResourceLocation id = new ResourceLocation(namespace.id, path == null ? Lang.asId(name()) : path);
|
||||||
|
if (optional) {
|
||||||
|
tag = optionalTag(ForgeRegistries.RECIPE_SERIALIZERS, id);
|
||||||
|
} else {
|
||||||
|
tag = TagKey.create(Registries.RECIPE_SERIALIZER, id);
|
||||||
|
}
|
||||||
|
this.alwaysDatagen = alwaysDatagen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean matches(RecipeSerializer<?> recipeSerializer) {
|
||||||
|
return ForgeRegistries.RECIPE_SERIALIZERS.getHolder(recipeSerializer).orElseThrow().is(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void init() {}
|
||||||
|
}
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
AllBlockTags.init();
|
AllBlockTags.init();
|
||||||
AllItemTags.init();
|
AllItemTags.init();
|
||||||
AllFluidTags.init();
|
AllFluidTags.init();
|
||||||
AllEntityTags.init();
|
AllEntityTags.init();
|
||||||
|
AllRecipeSerializerTags.init();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,10 +16,10 @@ import com.simibubi.create.content.decoration.palettes.AllPaletteBlocks;
|
||||||
import com.simibubi.create.content.equipment.potatoCannon.BuiltinPotatoProjectileTypes;
|
import com.simibubi.create.content.equipment.potatoCannon.BuiltinPotatoProjectileTypes;
|
||||||
import com.simibubi.create.content.fluids.tank.BoilerHeaters;
|
import com.simibubi.create.content.fluids.tank.BoilerHeaters;
|
||||||
import com.simibubi.create.content.kinetics.TorquePropagator;
|
import com.simibubi.create.content.kinetics.TorquePropagator;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.AllFanProcessingTypes;
|
||||||
import com.simibubi.create.content.kinetics.mechanicalArm.AllArmInteractionPointTypes;
|
import com.simibubi.create.content.kinetics.mechanicalArm.AllArmInteractionPointTypes;
|
||||||
import com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours;
|
import com.simibubi.create.content.redstone.displayLink.AllDisplayBehaviours;
|
||||||
import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler;
|
import com.simibubi.create.content.redstone.link.RedstoneLinkNetworkHandler;
|
||||||
import com.simibubi.create.content.schematics.SchematicInstances;
|
|
||||||
import com.simibubi.create.content.schematics.ServerSchematicLoader;
|
import com.simibubi.create.content.schematics.ServerSchematicLoader;
|
||||||
import com.simibubi.create.content.trains.GlobalRailwayManager;
|
import com.simibubi.create.content.trains.GlobalRailwayManager;
|
||||||
import com.simibubi.create.content.trains.bogey.BogeySizes;
|
import com.simibubi.create.content.trains.bogey.BogeySizes;
|
||||||
|
@ -30,6 +30,7 @@ import com.simibubi.create.foundation.damageTypes.DamageTypeDataProvider;
|
||||||
import com.simibubi.create.foundation.damageTypes.DamageTypeTagGen;
|
import com.simibubi.create.foundation.damageTypes.DamageTypeTagGen;
|
||||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||||
import com.simibubi.create.foundation.data.LangMerger;
|
import com.simibubi.create.foundation.data.LangMerger;
|
||||||
|
import com.simibubi.create.foundation.data.RecipeSerializerTagGen;
|
||||||
import com.simibubi.create.foundation.data.TagGen;
|
import com.simibubi.create.foundation.data.TagGen;
|
||||||
import com.simibubi.create.foundation.data.recipe.MechanicalCraftingRecipeGen;
|
import com.simibubi.create.foundation.data.recipe.MechanicalCraftingRecipeGen;
|
||||||
import com.simibubi.create.foundation.data.recipe.ProcessingRecipeGen;
|
import com.simibubi.create.foundation.data.recipe.ProcessingRecipeGen;
|
||||||
|
@ -68,7 +69,7 @@ public class Create {
|
||||||
|
|
||||||
public static final String ID = "create";
|
public static final String ID = "create";
|
||||||
public static final String NAME = "Create";
|
public static final String NAME = "Create";
|
||||||
public static final String VERSION = "0.5.1d";
|
public static final String VERSION = "0.5.1e";
|
||||||
|
|
||||||
public static final Logger LOGGER = LogUtils.getLogger();
|
public static final Logger LOGGER = LogUtils.getLogger();
|
||||||
|
|
||||||
|
@ -110,6 +111,7 @@ public class Create {
|
||||||
|
|
||||||
AllSoundEvents.prepare();
|
AllSoundEvents.prepare();
|
||||||
AllTags.init();
|
AllTags.init();
|
||||||
|
AllCreativeModeTabs.register(modEventBus);
|
||||||
AllBlocks.register();
|
AllBlocks.register();
|
||||||
AllItems.register();
|
AllItems.register();
|
||||||
AllFluids.register();
|
AllFluids.register();
|
||||||
|
@ -122,20 +124,24 @@ public class Create {
|
||||||
AllParticleTypes.register(modEventBus);
|
AllParticleTypes.register(modEventBus);
|
||||||
AllStructureProcessorTypes.register(modEventBus);
|
AllStructureProcessorTypes.register(modEventBus);
|
||||||
AllEntityDataSerializers.register(modEventBus);
|
AllEntityDataSerializers.register(modEventBus);
|
||||||
|
AllPackets.registerPackets();
|
||||||
AllFeatures.register(modEventBus);
|
AllFeatures.register(modEventBus);
|
||||||
AllPlacementModifiers.register(modEventBus);
|
AllPlacementModifiers.register(modEventBus);
|
||||||
AllCreativeModeTabs.register(modEventBus);
|
|
||||||
BogeySizes.init();
|
|
||||||
AllBogeyStyles.register();
|
|
||||||
|
|
||||||
AllConfigs.register(modLoadingContext);
|
AllConfigs.register(modLoadingContext);
|
||||||
|
|
||||||
|
// FIXME: some of these registrations are not thread-safe
|
||||||
AllMovementBehaviours.registerDefaults();
|
AllMovementBehaviours.registerDefaults();
|
||||||
AllInteractionBehaviours.registerDefaults();
|
AllInteractionBehaviours.registerDefaults();
|
||||||
AllDisplayBehaviours.registerDefaults();
|
AllDisplayBehaviours.registerDefaults();
|
||||||
ContraptionMovementSetting.registerDefaults();
|
ContraptionMovementSetting.registerDefaults();
|
||||||
AllArmInteractionPointTypes.register();
|
AllArmInteractionPointTypes.register();
|
||||||
|
AllFanProcessingTypes.register();
|
||||||
BlockSpoutingBehaviour.registerDefaults();
|
BlockSpoutingBehaviour.registerDefaults();
|
||||||
|
BogeySizes.init();
|
||||||
|
AllBogeyStyles.register();
|
||||||
|
// ----
|
||||||
|
|
||||||
ComputerCraftProxy.register();
|
ComputerCraftProxy.register();
|
||||||
|
|
||||||
ForgeMod.enableMilkFluid();
|
ForgeMod.enableMilkFluid();
|
||||||
|
@ -147,20 +153,24 @@ public class Create {
|
||||||
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
|
||||||
|
|
||||||
|
// FIXME: this is not thread-safe
|
||||||
Mods.CURIOS.executeIfInstalled(() -> () -> Curios.init(modEventBus, forgeEventBus));
|
Mods.CURIOS.executeIfInstalled(() -> () -> Curios.init(modEventBus, forgeEventBus));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void init(final FMLCommonSetupEvent event) {
|
public static void init(final FMLCommonSetupEvent event) {
|
||||||
AllPackets.registerPackets();
|
AllFluids.registerFluidInteractions();
|
||||||
SchematicInstances.register();
|
|
||||||
BuiltinPotatoProjectileTypes.register();
|
|
||||||
|
|
||||||
event.enqueueWork(() -> {
|
event.enqueueWork(() -> {
|
||||||
|
// TODO: custom registration should all happen in one place
|
||||||
|
// Most registration happens in the constructor.
|
||||||
|
// These registrations use Create's registered objects directly so they must run after registration has finished.
|
||||||
|
BuiltinPotatoProjectileTypes.register();
|
||||||
|
BoilerHeaters.registerDefaults();
|
||||||
|
// --
|
||||||
|
|
||||||
AttachedRegistry.unwrapAll();
|
AttachedRegistry.unwrapAll();
|
||||||
AllAdvancements.register();
|
AllAdvancements.register();
|
||||||
AllTriggers.register();
|
AllTriggers.register();
|
||||||
BoilerHeaters.registerDefaults();
|
|
||||||
AllFluids.registerFluidInteractions();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +185,7 @@ public class Create {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.includeServer()) {
|
if (event.includeServer()) {
|
||||||
|
gen.addProvider(true, new RecipeSerializerTagGen(output, event.getLookupProvider(), event.getExistingFileHelper()));
|
||||||
gen.addProvider(true, new AllAdvancements(output));
|
gen.addProvider(true, new AllAdvancements(output));
|
||||||
gen.addProvider(true, new StandardRecipeGen(output));
|
gen.addProvider(true, new StandardRecipeGen(output));
|
||||||
gen.addProvider(true, new MechanicalCraftingRecipeGen(output));
|
gen.addProvider(true, new MechanicalCraftingRecipeGen(output));
|
||||||
|
|
|
@ -14,26 +14,42 @@ import net.minecraftforge.registries.ForgeRegistries;
|
||||||
* For compatibility with and without another mod present, we have to define load conditions of the specific code
|
* For compatibility with and without another mod present, we have to define load conditions of the specific code
|
||||||
*/
|
*/
|
||||||
public enum Mods {
|
public enum Mods {
|
||||||
DYNAMICTREES,
|
|
||||||
TCONSTRUCT,
|
|
||||||
CURIOS,
|
|
||||||
|
|
||||||
COMPUTERCRAFT,
|
COMPUTERCRAFT,
|
||||||
|
CONNECTIVITY,
|
||||||
|
CURIOS,
|
||||||
|
DYNAMICTREES,
|
||||||
|
OCCULTISM,
|
||||||
|
PACKETFIXER,
|
||||||
STORAGEDRAWERS,
|
STORAGEDRAWERS,
|
||||||
|
TCONSTRUCT,
|
||||||
XLPACKETS;
|
XLPACKETS;
|
||||||
|
|
||||||
/**
|
private final String id;
|
||||||
* @return a boolean of whether the mod is loaded or not based on mod id
|
|
||||||
*/
|
Mods() {
|
||||||
public boolean isLoaded() {
|
id = Lang.asId(name());
|
||||||
return ModList.get().isLoaded(asId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the mod id
|
* @return the mod id
|
||||||
*/
|
*/
|
||||||
public String asId() {
|
public String id() {
|
||||||
return Lang.asId(name());
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResourceLocation rl(String path) {
|
||||||
|
return new ResourceLocation(id, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Block getBlock(String id) {
|
||||||
|
return ForgeRegistries.BLOCKS.getValue(rl(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a boolean of whether the mod is loaded or not based on mod id
|
||||||
|
*/
|
||||||
|
public boolean isLoaded() {
|
||||||
|
return ModList.get().isLoaded(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,8 +72,4 @@ public enum Mods {
|
||||||
toExecute.get().run();
|
toExecute.get().run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Block getBlock(String id) {
|
|
||||||
return ForgeRegistries.BLOCKS.getValue(new ResourceLocation(asId(), id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
package com.simibubi.create.compat.curios;
|
package com.simibubi.create.compat.curios;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.AllTags;
|
||||||
import com.simibubi.create.content.equipment.armor.BacktankUtil;
|
import com.simibubi.create.content.equipment.armor.BacktankUtil;
|
||||||
import com.simibubi.create.content.equipment.goggles.GogglesItem;
|
import com.simibubi.create.content.equipment.goggles.GogglesItem;
|
||||||
import com.simibubi.create.AllTags;
|
|
||||||
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
@ -19,11 +24,6 @@ import top.theillusivec4.curios.api.SlotTypePreset;
|
||||||
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
|
import top.theillusivec4.curios.api.type.capability.ICuriosItemHandler;
|
||||||
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
|
import top.theillusivec4.curios.api.type.inventory.ICurioStacksHandler;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
public class Curios {
|
public class Curios {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -51,8 +51,8 @@ import com.simibubi.create.content.kinetics.crusher.AbstractCrushingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe;
|
import com.simibubi.create.content.kinetics.deployer.DeployerApplicationRecipe;
|
||||||
import com.simibubi.create.content.kinetics.deployer.ItemApplicationRecipe;
|
import com.simibubi.create.content.kinetics.deployer.ItemApplicationRecipe;
|
||||||
import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe;
|
import com.simibubi.create.content.kinetics.deployer.ManualApplicationRecipe;
|
||||||
import com.simibubi.create.content.kinetics.fan.HauntingRecipe;
|
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.fan.SplashingRecipe;
|
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity;
|
import com.simibubi.create.content.kinetics.press.MechanicalPressBlockEntity;
|
||||||
import com.simibubi.create.content.kinetics.press.PressingRecipe;
|
import com.simibubi.create.content.kinetics.press.PressingRecipe;
|
||||||
import com.simibubi.create.content.kinetics.saw.CuttingRecipe;
|
import com.simibubi.create.content.kinetics.saw.CuttingRecipe;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.simibubi.create.compat.jei.category;
|
package com.simibubi.create.compat.jei.category;
|
||||||
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
||||||
import com.simibubi.create.content.kinetics.fan.HauntingRecipe;
|
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe;
|
||||||
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
import com.simibubi.create.foundation.gui.AllGuiTextures;
|
||||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package com.simibubi.create.compat.jei.category;
|
package com.simibubi.create.compat.jei.category;
|
||||||
|
|
||||||
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
import com.simibubi.create.compat.jei.category.animations.AnimatedKinetics;
|
||||||
import com.simibubi.create.content.kinetics.fan.SplashingRecipe;
|
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe;
|
||||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||||
|
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
|
|
|
@ -2,17 +2,17 @@ package com.simibubi.create.compat.storageDrawers;
|
||||||
|
|
||||||
import com.simibubi.create.compat.Mods;
|
import com.simibubi.create.compat.Mods;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
|
import com.simibubi.create.foundation.utility.RegisteredObjects;
|
||||||
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import net.minecraftforge.items.IItemHandler;
|
import net.minecraftforge.items.IItemHandler;
|
||||||
|
|
||||||
public class StorageDrawers {
|
public class StorageDrawers {
|
||||||
|
|
||||||
public static boolean isDrawer(BlockEntity be) {
|
public static boolean isDrawer(BlockEntity be) {
|
||||||
return be != null && Mods.STORAGEDRAWERS.asId()
|
return be != null && Mods.STORAGEDRAWERS.id()
|
||||||
.equals(BlockEntityType.getKey(be.getType())
|
.equals(RegisteredObjects.getKeyOrThrow(be.getType())
|
||||||
.getNamespace());
|
.getNamespace());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -336,7 +336,7 @@ public class BlockMovementChecks {
|
||||||
return direction == state.getValue(StickerBlock.FACING)
|
return direction == state.getValue(StickerBlock.FACING)
|
||||||
&& !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite());
|
&& !isNotSupportive(world.getBlockState(pos.relative(direction)), direction.getOpposite());
|
||||||
}
|
}
|
||||||
if (block instanceof AbstractBogeyBlock bogey)
|
if (block instanceof AbstractBogeyBlock<?> bogey)
|
||||||
return bogey.getStickySurfaces(world, pos, state)
|
return bogey.getStickySurfaces(world, pos, state)
|
||||||
.contains(direction);
|
.contains(direction);
|
||||||
if (block instanceof WhistleBlock)
|
if (block instanceof WhistleBlock)
|
||||||
|
|
|
@ -1379,7 +1379,7 @@ public abstract class Contraption {
|
||||||
return blocks.values();
|
return blocks.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection<BlockEntity> getSpecialRenderedTEs() {
|
public Collection<BlockEntity> getSpecialRenderedBEs() {
|
||||||
return specialRenderedBlockEntities;
|
return specialRenderedBlockEntities;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import com.simibubi.create.AllDamageTypes;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
import org.apache.commons.lang3.mutable.MutableFloat;
|
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||||
import org.apache.commons.lang3.mutable.MutableObject;
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
@ -18,6 +16,7 @@ import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.AllDamageTypes;
|
||||||
import com.simibubi.create.AllMovementBehaviours;
|
import com.simibubi.create.AllMovementBehaviours;
|
||||||
import com.simibubi.create.AllPackets;
|
import com.simibubi.create.AllPackets;
|
||||||
import com.simibubi.create.content.contraptions.AbstractContraptionEntity.ContraptionRotationState;
|
import com.simibubi.create.content.contraptions.AbstractContraptionEntity.ContraptionRotationState;
|
||||||
|
|
|
@ -14,17 +14,46 @@ public class ContraptionData {
|
||||||
/**
|
/**
|
||||||
* A sane, default maximum for contraption data size.
|
* A sane, default maximum for contraption data size.
|
||||||
*/
|
*/
|
||||||
public static final int DEFAULT_MAX = 2_000_000;
|
public static final int DEFAULT_LIMIT = 2_000_000;
|
||||||
|
/**
|
||||||
|
* Connectivity expands the NBT packet limit to 2 GB.
|
||||||
|
*/
|
||||||
|
public static final int CONNECTIVITY_LIMIT = Integer.MAX_VALUE;
|
||||||
|
/**
|
||||||
|
* Packet Fixer expands the NBT packet limit to 200 MB.
|
||||||
|
*/
|
||||||
|
public static final int PACKET_FIXER_LIMIT = 209_715_200;
|
||||||
/**
|
/**
|
||||||
* XL Packets expands the NBT packet limit to 2 GB.
|
* XL Packets expands the NBT packet limit to 2 GB.
|
||||||
*/
|
*/
|
||||||
public static final int EXPANDED_MAX = 2_000_000_000;
|
public static final int XL_PACKETS_LIMIT = 2_000_000_000;
|
||||||
/**
|
/**
|
||||||
* Minecart item sizes are limited by the vanilla slot change packet ({@link ClientboundContainerSetSlotPacket}).
|
* Minecart item sizes are limited by the vanilla slot change packet ({@link ClientboundContainerSetSlotPacket}).
|
||||||
* {@link ContraptionData#DEFAULT_MAX} is used as the default.
|
* {@link #DEFAULT_LIMIT} is used as the default.
|
||||||
* XL Packets expands the size limit to ~2 GB. If the mod is loaded, we take advantage of it and use the higher limit.
|
* Connectivity, PacketFixer, and XL Packets expand the size limit.
|
||||||
|
* If one of these mods is loaded, we take advantage of it and use the higher limit.
|
||||||
*/
|
*/
|
||||||
public static final int PICKUP_MAX = Mods.XLPACKETS.isLoaded() ? EXPANDED_MAX : DEFAULT_MAX;
|
public static final int PICKUP_LIMIT;
|
||||||
|
|
||||||
|
static {
|
||||||
|
int limit = DEFAULT_LIMIT;
|
||||||
|
|
||||||
|
// Check from largest to smallest to use the smallest limit if multiple mods are loaded.
|
||||||
|
// It is necessary to use the smallest limit because even if multiple mods are loaded,
|
||||||
|
// not all of their mixins may be applied. Therefore, it is safest to only assume that
|
||||||
|
// the mod with the smallest limit is actually active.
|
||||||
|
if (Mods.CONNECTIVITY.isLoaded()) {
|
||||||
|
limit = CONNECTIVITY_LIMIT;
|
||||||
|
}
|
||||||
|
if (Mods.XLPACKETS.isLoaded()) {
|
||||||
|
limit = XL_PACKETS_LIMIT;
|
||||||
|
}
|
||||||
|
if (Mods.PACKETFIXER.isLoaded()) {
|
||||||
|
limit = PACKET_FIXER_LIMIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
PICKUP_LIMIT = limit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return true if the given NBT is too large for a contraption to be synced to clients.
|
* @return true if the given NBT is too large for a contraption to be synced to clients.
|
||||||
|
@ -38,7 +67,7 @@ public class ContraptionData {
|
||||||
* @return true if the given NBT is too large for a contraption to be picked up with a wrench.
|
* @return true if the given NBT is too large for a contraption to be picked up with a wrench.
|
||||||
*/
|
*/
|
||||||
public static boolean isTooLargeForPickup(CompoundTag data) {
|
public static boolean isTooLargeForPickup(CompoundTag data) {
|
||||||
return packetSize(data) > PICKUP_MAX;
|
return packetSize(data) > PICKUP_LIMIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,6 @@ import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.BlockItem;
|
import net.minecraft.world.item.BlockItem;
|
||||||
|
|
|
@ -10,7 +10,6 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.particles.BlockParticleOption;
|
import net.minecraft.core.particles.BlockParticleOption;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
|
|
|
@ -34,7 +34,6 @@ import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
@ -118,9 +117,9 @@ public class ContraptionRenderDispatcher {
|
||||||
ContraptionWorld contraptionWorld = c.getContraptionWorld();
|
ContraptionWorld contraptionWorld = c.getContraptionWorld();
|
||||||
|
|
||||||
BlockPos origin = c.anchor;
|
BlockPos origin = c.anchor;
|
||||||
int height = contraptionWorld.getHeight();
|
|
||||||
int minBuildHeight = contraptionWorld.getMinBuildHeight();
|
int minBuildHeight = contraptionWorld.getMinBuildHeight();
|
||||||
VirtualRenderWorld renderWorld = new VirtualRenderWorld(world, origin, height, minBuildHeight) {
|
int height = contraptionWorld.getHeight();
|
||||||
|
VirtualRenderWorld renderWorld = new VirtualRenderWorld(world, minBuildHeight, height, origin) {
|
||||||
@Override
|
@Override
|
||||||
public boolean supportsFlywheel() {
|
public boolean supportsFlywheel() {
|
||||||
return canInstance();
|
return canInstance();
|
||||||
|
@ -134,13 +133,13 @@ public class ContraptionRenderDispatcher {
|
||||||
// FIXME 1.20 this '0' used to be Block.UPDATE_SUPPRESS_LIGHT, yet VirtualRenderWorld didn't actually parse the flags at all
|
// FIXME 1.20 this '0' used to be Block.UPDATE_SUPPRESS_LIGHT, yet VirtualRenderWorld didn't actually parse the flags at all
|
||||||
renderWorld.setBlock(info.pos(), info.state(), 0);
|
renderWorld.setBlock(info.pos(), info.state(), 0);
|
||||||
|
|
||||||
renderWorld.runLightingEngine();
|
renderWorld.runLightEngine();
|
||||||
return renderWorld;
|
return renderWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderBlockEntities(Level world, VirtualRenderWorld renderWorld, Contraption c,
|
public static void renderBlockEntities(Level world, VirtualRenderWorld renderWorld, Contraption c,
|
||||||
ContraptionMatrices matrices, MultiBufferSource buffer) {
|
ContraptionMatrices matrices, MultiBufferSource buffer) {
|
||||||
BlockEntityRenderHelper.renderBlockEntities(world, renderWorld, c.getSpecialRenderedTEs(),
|
BlockEntityRenderHelper.renderBlockEntities(world, renderWorld, c.getSpecialRenderedBEs(),
|
||||||
matrices.getModelViewProjection(), matrices.getLight(), buffer);
|
matrices.getModelViewProjection(), matrices.getLight(), buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import net.minecraftforge.network.NetworkEvent.Context;
|
import net.minecraftforge.network.NetworkEvent.Context;
|
||||||
import net.minecraftforge.network.PacketDistributor;
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
|
|
|
@ -31,15 +31,14 @@ public class CopycatBarsModel extends CopycatModel {
|
||||||
protected List<BakedQuad> getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material,
|
protected List<BakedQuad> getCroppedQuads(BlockState state, Direction side, RandomSource rand, BlockState material,
|
||||||
ModelData wrappedData, RenderType renderType) {
|
ModelData wrappedData, RenderType renderType) {
|
||||||
BakedModel model = getModelOf(material);
|
BakedModel model = getModelOf(material);
|
||||||
List<BakedQuad> templateQuads = model.getQuads(material, null, rand, wrappedData, renderType);
|
|
||||||
List<BakedQuad> superQuads = originalModel.getQuads(state, side, rand, wrappedData, renderType);
|
List<BakedQuad> superQuads = originalModel.getQuads(state, side, rand, wrappedData, renderType);
|
||||||
List<BakedQuad> quads = new ArrayList<>();
|
|
||||||
TextureAtlasSprite targetSprite = model.getParticleIcon(wrappedData);
|
TextureAtlasSprite targetSprite = model.getParticleIcon(wrappedData);
|
||||||
|
|
||||||
boolean vertical = state.getValue(CopycatPanelBlock.FACING)
|
boolean vertical = state.getValue(CopycatPanelBlock.FACING)
|
||||||
.getAxis() == Axis.Y;
|
.getAxis() == Axis.Y;
|
||||||
|
|
||||||
if (side != null && (vertical || side.getAxis() == Axis.Y))
|
if (side != null && (vertical || side.getAxis() == Axis.Y)) {
|
||||||
|
List<BakedQuad> templateQuads = model.getQuads(material, null, rand, wrappedData, renderType);
|
||||||
for (int i = 0; i < templateQuads.size(); i++) {
|
for (int i = 0; i < templateQuads.size(); i++) {
|
||||||
BakedQuad quad = templateQuads.get(i);
|
BakedQuad quad = templateQuads.get(i);
|
||||||
if (quad.getDirection() != Direction.UP)
|
if (quad.getDirection() != Direction.UP)
|
||||||
|
@ -47,10 +46,13 @@ public class CopycatBarsModel extends CopycatModel {
|
||||||
targetSprite = quad.getSprite();
|
targetSprite = quad.getSprite();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (targetSprite == null)
|
if (targetSprite == null)
|
||||||
return superQuads;
|
return superQuads;
|
||||||
|
|
||||||
|
List<BakedQuad> quads = new ArrayList<>();
|
||||||
|
|
||||||
for (int i = 0; i < superQuads.size(); i++) {
|
for (int i = 0; i < superQuads.size(); i++) {
|
||||||
BakedQuad quad = superQuads.get(i);
|
BakedQuad quad = superQuads.get(i);
|
||||||
TextureAtlasSprite original = quad.getSprite();
|
TextureAtlasSprite original = quad.getSprite();
|
||||||
|
|
|
@ -16,7 +16,6 @@ import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.registries.Registries;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.nbt.NbtUtils;
|
import net.minecraft.nbt.NbtUtils;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.content.decoration.copycat;
|
package com.simibubi.create.content.decoration.copycat;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -110,14 +111,24 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
|
||||||
|
|
||||||
// Rubidium: render side!=null versions of the base material during side==null,
|
// Rubidium: render side!=null versions of the base material during side==null,
|
||||||
// to avoid getting culled away
|
// to avoid getting culled away
|
||||||
if (side == null && state.getBlock() instanceof CopycatBlock ccb)
|
if (side == null && state.getBlock() instanceof CopycatBlock ccb) {
|
||||||
|
boolean immutable = true;
|
||||||
for (Direction nonOcclusionSide : Iterate.directions)
|
for (Direction nonOcclusionSide : Iterate.directions)
|
||||||
if (ccb.shouldFaceAlwaysRender(state, nonOcclusionSide))
|
if (ccb.shouldFaceAlwaysRender(state, nonOcclusionSide)) {
|
||||||
|
if (immutable) {
|
||||||
|
croppedQuads = new ArrayList<>(croppedQuads);
|
||||||
|
immutable = false;
|
||||||
|
}
|
||||||
croppedQuads.addAll(getCroppedQuads(state, nonOcclusionSide, rand, material, wrappedData, renderType));
|
croppedQuads.addAll(getCroppedQuads(state, nonOcclusionSide, rand, material, wrappedData, renderType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return croppedQuads;
|
return croppedQuads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The returned list must not be mutated.
|
||||||
|
*/
|
||||||
protected abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, RandomSource rand,
|
protected abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, RandomSource rand,
|
||||||
BlockState material, ModelData wrappedData, RenderType renderType);
|
BlockState material, ModelData wrappedData, RenderType renderType);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.content.equipment.armor;
|
package com.simibubi.create.content.equipment.armor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
|
@ -22,8 +23,6 @@ import net.minecraftforge.event.entity.living.LivingEvent.LivingTickEvent;
|
||||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@EventBusSubscriber
|
@EventBusSubscriber
|
||||||
public class DivingHelmetItem extends BaseArmorItem {
|
public class DivingHelmetItem extends BaseArmorItem {
|
||||||
public static final EquipmentSlot SLOT = EquipmentSlot.HEAD;
|
public static final EquipmentSlot SLOT = EquipmentSlot.HEAD;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
import com.google.j2objc.annotations.ReflectionSupport.Level;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.content.equipment.blueprint.BlueprintEntity.BlueprintCraftingInventory;
|
import com.simibubi.create.content.equipment.blueprint.BlueprintEntity.BlueprintCraftingInventory;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.simibubi.create.content.equipment.goggles;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
package com.simibubi.create.content.equipment.potatoCannon;
|
package com.simibubi.create.content.equipment.potatoCannon;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.simibubi.create.AllDamageTypes;
|
import com.simibubi.create.AllDamageTypes;
|
||||||
import com.simibubi.create.AllEnchantments;
|
import com.simibubi.create.AllEnchantments;
|
||||||
import com.simibubi.create.AllSoundEvents;
|
import com.simibubi.create.AllSoundEvents;
|
||||||
|
@ -37,8 +39,6 @@ import net.minecraftforge.entity.IEntityAdditionalSpawnData;
|
||||||
import net.minecraftforge.items.ItemHandlerHelper;
|
import net.minecraftforge.items.ItemHandlerHelper;
|
||||||
import net.minecraftforge.network.NetworkHooks;
|
import net.minecraftforge.network.NetworkHooks;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
public class PotatoProjectileEntity extends AbstractHurtingProjectile implements IEntityAdditionalSpawnData {
|
public class PotatoProjectileEntity extends AbstractHurtingProjectile implements IEntityAdditionalSpawnData {
|
||||||
|
|
||||||
protected PotatoCannonProjectileType type;
|
protected PotatoCannonProjectileType type;
|
||||||
|
|
|
@ -13,7 +13,6 @@ import com.simibubi.create.foundation.item.render.SimpleCustomRenderer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
import net.minecraft.world.entity.vehicle.AbstractMinecart;
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.simibubi.create.content.kinetics.belt.transport;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import com.simibubi.create.content.kinetics.belt.BeltHelper;
|
import com.simibubi.create.content.kinetics.belt.BeltHelper;
|
||||||
import com.simibubi.create.content.kinetics.fan.FanProcessing;
|
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||||
|
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
@ -25,7 +25,7 @@ public class TransportedItemStack implements Comparable<TransportedItemStack> {
|
||||||
public float prevBeltPosition;
|
public float prevBeltPosition;
|
||||||
public float prevSideOffset;
|
public float prevSideOffset;
|
||||||
|
|
||||||
public FanProcessing.Type processedBy;
|
public FanProcessingType processedBy;
|
||||||
public int processingTime;
|
public int processingTime;
|
||||||
|
|
||||||
public TransportedItemStack(ItemStack stack) {
|
public TransportedItemStack(ItemStack stack) {
|
||||||
|
|
|
@ -16,4 +16,9 @@ public abstract class AbstractCrushingRecipe extends ProcessingRecipe<RecipeWrap
|
||||||
protected int getMaxInputCount() {
|
protected int getMaxInputCount() {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canSpecifyDuration() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import net.minecraft.core.Direction.Axis;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
|
@ -10,7 +10,9 @@ import com.simibubi.create.AllTags;
|
||||||
import com.simibubi.create.content.decoration.copycat.CopycatBlock;
|
import com.simibubi.create.content.decoration.copycat.CopycatBlock;
|
||||||
import com.simibubi.create.content.kinetics.belt.behaviour.TransportedItemStackHandlerBehaviour;
|
import com.simibubi.create.content.kinetics.belt.behaviour.TransportedItemStackHandlerBehaviour;
|
||||||
import com.simibubi.create.content.kinetics.belt.behaviour.TransportedItemStackHandlerBehaviour.TransportedResult;
|
import com.simibubi.create.content.kinetics.belt.behaviour.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||||
import com.simibubi.create.content.kinetics.fan.FanProcessing.Type;
|
import com.simibubi.create.content.kinetics.fan.processing.AllFanProcessingTypes;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.FanProcessing;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
|
@ -29,7 +31,6 @@ import net.minecraft.world.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.material.Fluids;
|
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
@ -49,7 +50,7 @@ public class AirCurrent {
|
||||||
public boolean pushing;
|
public boolean pushing;
|
||||||
public float maxDistance;
|
public float maxDistance;
|
||||||
|
|
||||||
protected List<Pair<TransportedItemStackHandlerBehaviour, FanProcessing.Type>> affectedItemHandlers =
|
protected List<Pair<TransportedItemStackHandlerBehaviour, FanProcessingType>> affectedItemHandlers =
|
||||||
new ArrayList<>();
|
new ArrayList<>();
|
||||||
protected List<Entity> caughtEntities = new ArrayList<>();
|
protected List<Entity> caughtEntities = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -110,14 +111,14 @@ public class AirCurrent {
|
||||||
((ServerPlayer) entity).connection.aboveGroundTickCount = 0;
|
((ServerPlayer) entity).connection.aboveGroundTickCount = 0;
|
||||||
|
|
||||||
entityDistance -= .5f;
|
entityDistance -= .5f;
|
||||||
FanProcessing.Type processingType = getSegmentAt((float) entityDistance);
|
FanProcessingType processingType = getSegmentAt((float) entityDistance);
|
||||||
|
|
||||||
if (processingType == null || processingType == Type.NONE)
|
if (processingType == AllFanProcessingTypes.NONE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (entity instanceof ItemEntity itemEntity) {
|
if (entity instanceof ItemEntity itemEntity) {
|
||||||
if (world.isClientSide) {
|
if (world != null && world.isClientSide) {
|
||||||
processingType.spawnParticlesForProcessing(world, entity.position());
|
processingType.spawnProcessingParticles(world, entity.position());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (FanProcessing.canProcess(itemEntity, processingType))
|
if (FanProcessing.canProcess(itemEntity, processingType))
|
||||||
|
@ -127,7 +128,8 @@ public class AirCurrent {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
processingType.affectEntity(entity, world);
|
if (world != null)
|
||||||
|
processingType.affectEntity(entity, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -155,7 +157,7 @@ public class AirCurrent {
|
||||||
AirCurrentSegment currentSegment = new AirCurrentSegment();
|
AirCurrentSegment currentSegment = new AirCurrentSegment();
|
||||||
segments.clear();
|
segments.clear();
|
||||||
currentSegment.startOffset = 0;
|
currentSegment.startOffset = 0;
|
||||||
FanProcessing.Type type = Type.NONE;
|
FanProcessingType type = AllFanProcessingTypes.NONE;
|
||||||
|
|
||||||
int limit = (int) (maxDistance + .5f);
|
int limit = (int) (maxDistance + .5f);
|
||||||
int searchStart = pushing ? 0 : limit;
|
int searchStart = pushing ? 0 : limit;
|
||||||
|
@ -164,8 +166,8 @@ public class AirCurrent {
|
||||||
|
|
||||||
for (int i = searchStart; i * searchStep <= searchEnd * searchStep; i += searchStep) {
|
for (int i = searchStart; i * searchStep <= searchEnd * searchStep; i += searchStep) {
|
||||||
BlockPos currentPos = start.relative(direction, i);
|
BlockPos currentPos = start.relative(direction, i);
|
||||||
FanProcessing.Type newType = FanProcessing.Type.byBlock(world, currentPos);
|
FanProcessingType newType = FanProcessingType.getAt(world, currentPos);
|
||||||
if (newType != Type.NONE)
|
if (newType != AllFanProcessingTypes.NONE)
|
||||||
type = newType;
|
type = newType;
|
||||||
if (currentSegment.type != type || currentSegment.startOffset == 0) {
|
if (currentSegment.type != type || currentSegment.startOffset == 0) {
|
||||||
currentSegment.endOffset = i;
|
currentSegment.endOffset = i;
|
||||||
|
@ -258,21 +260,18 @@ public class AirCurrent {
|
||||||
BlockPos start = source.getAirCurrentPos();
|
BlockPos start = source.getAirCurrentPos();
|
||||||
affectedItemHandlers.clear();
|
affectedItemHandlers.clear();
|
||||||
for (int i = 0; i < maxDistance + 1; i++) {
|
for (int i = 0; i < maxDistance + 1; i++) {
|
||||||
Type type = getSegmentAt(i);
|
FanProcessingType segmentType = getSegmentAt(i);
|
||||||
if (type == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int offset : Iterate.zeroAndOne) {
|
for (int offset : Iterate.zeroAndOne) {
|
||||||
BlockPos pos = start.relative(direction, i)
|
BlockPos pos = start.relative(direction, i)
|
||||||
.below(offset);
|
.below(offset);
|
||||||
TransportedItemStackHandlerBehaviour behaviour =
|
TransportedItemStackHandlerBehaviour behaviour =
|
||||||
BlockEntityBehaviour.get(world, pos, TransportedItemStackHandlerBehaviour.TYPE);
|
BlockEntityBehaviour.get(world, pos, TransportedItemStackHandlerBehaviour.TYPE);
|
||||||
FanProcessing.Type typeAtHandler = type;
|
if (behaviour == null)
|
||||||
if (world.getFluidState(pos)
|
continue;
|
||||||
.is(Fluids.WATER))
|
FanProcessingType type = FanProcessingType.getAt(world, pos);
|
||||||
typeAtHandler = Type.SPLASHING;
|
if (type == AllFanProcessingTypes.NONE)
|
||||||
if (behaviour != null)
|
type = segmentType;
|
||||||
affectedItemHandlers.add(Pair.of(behaviour, typeAtHandler));
|
affectedItemHandlers.add(Pair.of(behaviour, type));
|
||||||
if (direction.getAxis()
|
if (direction.getAxis()
|
||||||
.isVertical())
|
.isVertical())
|
||||||
break;
|
break;
|
||||||
|
@ -281,15 +280,14 @@ public class AirCurrent {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void tickAffectedHandlers() {
|
public void tickAffectedHandlers() {
|
||||||
for (Pair<TransportedItemStackHandlerBehaviour, Type> pair : affectedItemHandlers) {
|
for (Pair<TransportedItemStackHandlerBehaviour, FanProcessingType> pair : affectedItemHandlers) {
|
||||||
TransportedItemStackHandlerBehaviour handler = pair.getKey();
|
TransportedItemStackHandlerBehaviour handler = pair.getKey();
|
||||||
Level world = handler.getWorld();
|
Level world = handler.getWorld();
|
||||||
FanProcessing.Type processingType = pair.getRight();
|
FanProcessingType processingType = pair.getRight();
|
||||||
|
|
||||||
handler.handleProcessingOnAllItems((transported) -> {
|
handler.handleProcessingOnAllItems(transported -> {
|
||||||
if (world.isClientSide) {
|
if (world.isClientSide) {
|
||||||
if (world != null)
|
processingType.spawnProcessingParticles(world, handler.getWorldPositionOf(transported));
|
||||||
processingType.spawnParticlesForProcessing(world, handler.getWorldPositionOf(transported));
|
|
||||||
return TransportedResult.doNothing();
|
return TransportedResult.doNothing();
|
||||||
}
|
}
|
||||||
TransportedResult applyProcessing = FanProcessing.applyProcessing(transported, world, processingType);
|
TransportedResult applyProcessing = FanProcessing.applyProcessing(transported, world, processingType);
|
||||||
|
@ -304,7 +302,7 @@ public class AirCurrent {
|
||||||
return AllTags.AllBlockTags.FAN_TRANSPARENT.matches(state);
|
return AllTags.AllBlockTags.FAN_TRANSPARENT.matches(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
public FanProcessing.Type getSegmentAt(float offset) {
|
public FanProcessingType getSegmentAt(float offset) {
|
||||||
for (AirCurrentSegment airCurrentSegment : segments) {
|
for (AirCurrentSegment airCurrentSegment : segments) {
|
||||||
if (offset > airCurrentSegment.endOffset && pushing)
|
if (offset > airCurrentSegment.endOffset && pushing)
|
||||||
continue;
|
continue;
|
||||||
|
@ -312,11 +310,11 @@ public class AirCurrent {
|
||||||
continue;
|
continue;
|
||||||
return airCurrentSegment.type;
|
return airCurrentSegment.type;
|
||||||
}
|
}
|
||||||
return FanProcessing.Type.NONE;
|
return AllFanProcessingTypes.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AirCurrentSegment {
|
public static class AirCurrentSegment {
|
||||||
FanProcessing.Type type;
|
FanProcessingType type;
|
||||||
int startOffset;
|
int startOffset;
|
||||||
int endOffset;
|
int endOffset;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@ package com.simibubi.create.content.kinetics.fan;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.utility.Color;
|
import com.simibubi.create.content.kinetics.fan.processing.AllFanProcessingTypes;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.FanProcessingType;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
@ -13,16 +14,15 @@ import net.minecraft.client.particle.SimpleAnimatedParticle;
|
||||||
import net.minecraft.client.particle.SpriteSet;
|
import net.minecraft.client.particle.SpriteSet;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.particles.BlockParticleOption;
|
import net.minecraft.core.particles.ParticleOptions;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class AirFlowParticle extends SimpleAnimatedParticle {
|
public class AirFlowParticle extends SimpleAnimatedParticle {
|
||||||
|
|
||||||
private final IAirCurrentSource source;
|
private final IAirCurrentSource source;
|
||||||
|
private final Access access = new Access();
|
||||||
|
|
||||||
protected AirFlowParticle(ClientLevel world, IAirCurrentSource source, double x, double y, double z,
|
protected AirFlowParticle(ClientLevel world, IAirCurrentSource source, double x, double y, double z,
|
||||||
SpriteSet sprite) {
|
SpriteSet sprite) {
|
||||||
|
@ -32,11 +32,12 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
||||||
this.lifetime = 40;
|
this.lifetime = 40;
|
||||||
hasPhysics = false;
|
hasPhysics = false;
|
||||||
selectSprite(7);
|
selectSprite(7);
|
||||||
Vec3 offset = VecHelper.offsetRandomly(Vec3.ZERO, world.random, .25f);
|
Vec3 offset = VecHelper.offsetRandomly(Vec3.ZERO, random, .25f);
|
||||||
this.setPos(x + offset.x, y + offset.y, z + offset.z);
|
this.setPos(x + offset.x, y + offset.y, z + offset.z);
|
||||||
this.xo = x;
|
this.xo = x;
|
||||||
this.yo = y;
|
this.yo = y;
|
||||||
this.zo = z;
|
this.zo = z;
|
||||||
|
setColor(0xEEEEEE);
|
||||||
setAlpha(.25f);
|
setAlpha(.25f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,36 +49,44 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (source == null || source.isSourceRemoved()) {
|
if (source == null || source.isSourceRemoved()) {
|
||||||
dissipate();
|
remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.xo = this.x;
|
this.xo = this.x;
|
||||||
this.yo = this.y;
|
this.yo = this.y;
|
||||||
this.zo = this.z;
|
this.zo = this.z;
|
||||||
if (this.age++ >= this.lifetime) {
|
if (this.age++ >= this.lifetime) {
|
||||||
this.remove();
|
remove();
|
||||||
} else {
|
} else {
|
||||||
if (source.getAirCurrent() == null || !source.getAirCurrent().bounds.inflate(.25f).contains(x, y, z)) {
|
AirCurrent airCurrent = source.getAirCurrent();
|
||||||
dissipate();
|
if (airCurrent == null || !airCurrent.bounds.inflate(.25f).contains(x, y, z)) {
|
||||||
|
remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 directionVec = Vec3.atLowerCornerOf(source.getAirCurrent().direction.getNormal());
|
Vec3 directionVec = Vec3.atLowerCornerOf(airCurrent.direction.getNormal());
|
||||||
Vec3 motion = directionVec.scale(1 / 8f);
|
Vec3 motion = directionVec.scale(1 / 8f);
|
||||||
if (!source.getAirCurrent().pushing)
|
if (!source.getAirCurrent().pushing)
|
||||||
motion = motion.scale(-1);
|
motion = motion.scale(-1);
|
||||||
|
|
||||||
double distance = new Vec3(x, y, z).subtract(VecHelper.getCenterOf(source.getAirCurrentPos()))
|
double distance = new Vec3(x, y, z).subtract(VecHelper.getCenterOf(source.getAirCurrentPos()))
|
||||||
.multiply(directionVec).length() - .5f;
|
.multiply(directionVec).length() - .5f;
|
||||||
if (distance > source.getAirCurrent().maxDistance + 1 || distance < -.25f) {
|
if (distance > airCurrent.maxDistance + 1 || distance < -.25f) {
|
||||||
dissipate();
|
remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
motion = motion.scale(source.getAirCurrent().maxDistance - (distance - 1f)).scale(.5f);
|
motion = motion.scale(airCurrent.maxDistance - (distance - 1f)).scale(.5f);
|
||||||
selectSprite((int) Mth.clamp((distance / source.getAirCurrent().maxDistance) * 8 + level.random.nextInt(4),
|
|
||||||
0, 7));
|
|
||||||
|
|
||||||
morphType(distance);
|
FanProcessingType type = getType(distance);
|
||||||
|
if (type == AllFanProcessingTypes.NONE) {
|
||||||
|
setColor(0xEEEEEE);
|
||||||
|
setAlpha(.25f);
|
||||||
|
selectSprite((int) Mth.clamp((distance / airCurrent.maxDistance) * 8 + random.nextInt(4),
|
||||||
|
0, 7));
|
||||||
|
} else {
|
||||||
|
type.morphAirFlow(access, random);
|
||||||
|
selectSprite(random.nextInt(3));
|
||||||
|
}
|
||||||
|
|
||||||
xd = motion.x;
|
xd = motion.x;
|
||||||
yd = motion.y;
|
yd = motion.y;
|
||||||
|
@ -93,68 +102,10 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void morphType(double distance) {
|
private FanProcessingType getType(double distance) {
|
||||||
if (source.getAirCurrent() == null)
|
if (source.getAirCurrent() == null)
|
||||||
return;
|
return AllFanProcessingTypes.NONE;
|
||||||
FanProcessing.Type type = source.getAirCurrent().getSegmentAt((float) distance);
|
return source.getAirCurrent().getSegmentAt((float) distance);
|
||||||
|
|
||||||
if (type == FanProcessing.Type.SPLASHING) {
|
|
||||||
setColor(Color.mixColors(0x4499FF, 0x2277FF, level.random.nextFloat()));
|
|
||||||
setAlpha(1f);
|
|
||||||
selectSprite(level.random.nextInt(3));
|
|
||||||
if (level.random.nextFloat() < 1 / 32f)
|
|
||||||
level.addParticle(ParticleTypes.BUBBLE, x, y, z, xd * .125f, yd * .125f,
|
|
||||||
zd * .125f);
|
|
||||||
if (level.random.nextFloat() < 1 / 32f)
|
|
||||||
level.addParticle(ParticleTypes.BUBBLE_POP, x, y, z, xd * .125f, yd * .125f,
|
|
||||||
zd * .125f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == FanProcessing.Type.SMOKING) {
|
|
||||||
setColor(Color.mixColors(0x0, 0x555555, level.random.nextFloat()));
|
|
||||||
setAlpha(1f);
|
|
||||||
selectSprite(level.random.nextInt(3));
|
|
||||||
if (level.random.nextFloat() < 1 / 32f)
|
|
||||||
level.addParticle(ParticleTypes.SMOKE, x, y, z, xd * .125f, yd * .125f,
|
|
||||||
zd * .125f);
|
|
||||||
if (level.random.nextFloat() < 1 / 32f)
|
|
||||||
level.addParticle(ParticleTypes.LARGE_SMOKE, x, y, z, xd * .125f, yd * .125f,
|
|
||||||
zd * .125f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == FanProcessing.Type.HAUNTING) {
|
|
||||||
setColor(Color.mixColors(0x0, 0x126568, level.random.nextFloat()));
|
|
||||||
setAlpha(1f);
|
|
||||||
selectSprite(level.random.nextInt(3));
|
|
||||||
if (level.random.nextFloat() < 1 / 128f)
|
|
||||||
level.addParticle(ParticleTypes.SOUL_FIRE_FLAME, x, y, z, xd * .125f, yd * .125f,
|
|
||||||
zd * .125f);
|
|
||||||
if (level.random.nextFloat() < 1 / 32f)
|
|
||||||
level.addParticle(ParticleTypes.SMOKE, x, y, z, xd * .125f, yd * .125f,
|
|
||||||
zd * .125f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == FanProcessing.Type.BLASTING) {
|
|
||||||
setColor(Color.mixColors(0xFF4400, 0xFF8855, level.random.nextFloat()));
|
|
||||||
setAlpha(.5f);
|
|
||||||
selectSprite(level.random.nextInt(3));
|
|
||||||
if (level.random.nextFloat() < 1 / 32f)
|
|
||||||
level.addParticle(ParticleTypes.FLAME, x, y, z, xd * .25f, yd * .25f,
|
|
||||||
zd * .25f);
|
|
||||||
if (level.random.nextFloat() < 1 / 16f)
|
|
||||||
level.addParticle(new BlockParticleOption(ParticleTypes.BLOCK, Blocks.LAVA.defaultBlockState()), x, y,
|
|
||||||
z, xd * .25f, yd * .25f, zd * .25f);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == null) {
|
|
||||||
setColor(0xEEEEEE);
|
|
||||||
setAlpha(.25f);
|
|
||||||
setSize(.2f, .2f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void dissipate() {
|
|
||||||
remove();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getLightColor(float partialTick) {
|
public int getLightColor(float partialTick) {
|
||||||
|
@ -182,4 +133,21 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class Access implements FanProcessingType.AirFlowParticleAccess {
|
||||||
|
@Override
|
||||||
|
public void setColor(int color) {
|
||||||
|
AirFlowParticle.this.setColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAlpha(float alpha) {
|
||||||
|
AirFlowParticle.this.setAlpha(alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnExtraParticle(ParticleOptions options, float speedMultiplier) {
|
||||||
|
level.addParticle(options, x, y, z, xd * speedMultiplier, yd * speedMultiplier, zd * speedMultiplier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,451 +0,0 @@
|
||||||
package com.simibubi.create.content.kinetics.fan;
|
|
||||||
|
|
||||||
import static com.simibubi.create.content.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllDamageTypes;
|
|
||||||
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
|
||||||
import com.simibubi.create.AllRecipeTypes;
|
|
||||||
import com.simibubi.create.content.kinetics.belt.behaviour.TransportedItemStackHandlerBehaviour.TransportedResult;
|
|
||||||
import com.simibubi.create.content.kinetics.belt.transport.TransportedItemStack;
|
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
|
||||||
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
|
|
||||||
import com.simibubi.create.foundation.recipe.RecipeApplier;
|
|
||||||
import com.simibubi.create.foundation.utility.Color;
|
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
import com.simibubi.create.infrastructure.config.AllConfigs;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.RegistryAccess;
|
|
||||||
import net.minecraft.core.particles.DustParticleOptions;
|
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.sounds.SoundEvents;
|
|
||||||
import net.minecraft.sounds.SoundSource;
|
|
||||||
import net.minecraft.tags.BlockTags;
|
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.effect.MobEffectInstance;
|
|
||||||
import net.minecraft.world.effect.MobEffects;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
|
||||||
import net.minecraft.world.entity.EntityType;
|
|
||||||
import net.minecraft.world.entity.LivingEntity;
|
|
||||||
import net.minecraft.world.entity.animal.horse.Horse;
|
|
||||||
import net.minecraft.world.entity.animal.horse.SkeletonHorse;
|
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
|
||||||
import net.minecraft.world.entity.monster.EnderMan;
|
|
||||||
import net.minecraft.world.item.ItemStack;
|
|
||||||
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
|
|
||||||
import net.minecraft.world.item.crafting.BlastingRecipe;
|
|
||||||
import net.minecraft.world.item.crafting.RecipeType;
|
|
||||||
import net.minecraft.world.item.crafting.SmeltingRecipe;
|
|
||||||
import net.minecraft.world.item.crafting.SmokingRecipe;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.block.Block;
|
|
||||||
import net.minecraft.world.level.block.Blocks;
|
|
||||||
import net.minecraft.world.level.block.CampfireBlock;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraft.world.level.material.FluidState;
|
|
||||||
import net.minecraft.world.level.material.Fluids;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import net.minecraftforge.items.ItemStackHandler;
|
|
||||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
|
||||||
|
|
||||||
public class FanProcessing {
|
|
||||||
private static final RecipeWrapper RECIPE_WRAPPER = new RecipeWrapper(new ItemStackHandler(1));
|
|
||||||
private static final SplashingWrapper SPLASHING_WRAPPER = new SplashingWrapper();
|
|
||||||
private static final HauntingWrapper HAUNTING_WRAPPER = new HauntingWrapper();
|
|
||||||
|
|
||||||
public static boolean canProcess(ItemEntity entity, Type type) {
|
|
||||||
if (entity.getPersistentData()
|
|
||||||
.contains("CreateData")) {
|
|
||||||
CompoundTag compound = entity.getPersistentData()
|
|
||||||
.getCompound("CreateData");
|
|
||||||
if (compound.contains("Processing")) {
|
|
||||||
CompoundTag processing = compound.getCompound("Processing");
|
|
||||||
|
|
||||||
if (Type.valueOf(processing.getString("Type")) != type)
|
|
||||||
return type.canProcess(entity.getItem(), entity.level());
|
|
||||||
else if (processing.getInt("Time") >= 0)
|
|
||||||
return true;
|
|
||||||
else if (processing.getInt("Time") == -1)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return type.canProcess(entity.getItem(), entity.level());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isWashable(ItemStack stack, Level world) {
|
|
||||||
SPLASHING_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<SplashingRecipe> recipe = AllRecipeTypes.SPLASHING.find(SPLASHING_WRAPPER, world);
|
|
||||||
return recipe.isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isHauntable(ItemStack stack, Level world) {
|
|
||||||
HAUNTING_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(HAUNTING_WRAPPER, world);
|
|
||||||
return recipe.isPresent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean applyProcessing(ItemEntity entity, Type type) {
|
|
||||||
if (decrementProcessingTime(entity, type) != 0)
|
|
||||||
return false;
|
|
||||||
List<ItemStack> stacks = process(entity.getItem(), type, entity.level());
|
|
||||||
if (stacks == null)
|
|
||||||
return false;
|
|
||||||
if (stacks.isEmpty()) {
|
|
||||||
entity.discard();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
entity.setItem(stacks.remove(0));
|
|
||||||
for (ItemStack additional : stacks) {
|
|
||||||
ItemEntity entityIn = new ItemEntity(entity.level(), entity.getX(), entity.getY(), entity.getZ(), additional);
|
|
||||||
entityIn.setDeltaMovement(entity.getDeltaMovement());
|
|
||||||
entity.level().addFreshEntity(entityIn);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TransportedResult applyProcessing(TransportedItemStack transported, Level world, Type type) {
|
|
||||||
TransportedResult ignore = TransportedResult.doNothing();
|
|
||||||
if (transported.processedBy != type) {
|
|
||||||
transported.processedBy = type;
|
|
||||||
int timeModifierForStackSize = ((transported.stack.getCount() - 1) / 16) + 1;
|
|
||||||
int processingTime =
|
|
||||||
(int) (AllConfigs.server().kinetics.fanProcessingTime.get() * timeModifierForStackSize) + 1;
|
|
||||||
transported.processingTime = processingTime;
|
|
||||||
if (!type.canProcess(transported.stack, world))
|
|
||||||
transported.processingTime = -1;
|
|
||||||
return ignore;
|
|
||||||
}
|
|
||||||
if (transported.processingTime == -1)
|
|
||||||
return ignore;
|
|
||||||
if (transported.processingTime-- > 0)
|
|
||||||
return ignore;
|
|
||||||
|
|
||||||
List<ItemStack> stacks = process(transported.stack, type, world);
|
|
||||||
if (stacks == null)
|
|
||||||
return ignore;
|
|
||||||
|
|
||||||
List<TransportedItemStack> transportedStacks = new ArrayList<>();
|
|
||||||
for (ItemStack additional : stacks) {
|
|
||||||
TransportedItemStack newTransported = transported.getSimilar();
|
|
||||||
newTransported.stack = additional.copy();
|
|
||||||
transportedStacks.add(newTransported);
|
|
||||||
}
|
|
||||||
return TransportedResult.convertTo(transportedStacks);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<ItemStack> process(ItemStack stack, Type type, Level world) {
|
|
||||||
if (type == Type.SPLASHING) {
|
|
||||||
SPLASHING_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<SplashingRecipe> recipe = AllRecipeTypes.SPLASHING.find(SPLASHING_WRAPPER, world);
|
|
||||||
if (recipe.isPresent())
|
|
||||||
return RecipeApplier.applyRecipeOn(world, stack, recipe.get());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (type == Type.HAUNTING) {
|
|
||||||
HAUNTING_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(HAUNTING_WRAPPER, world);
|
|
||||||
if (recipe.isPresent())
|
|
||||||
return RecipeApplier.applyRecipeOn(world, stack, recipe.get());
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
RECIPE_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<SmokingRecipe> smokingRecipe = world.getRecipeManager()
|
|
||||||
.getRecipeFor(RecipeType.SMOKING, RECIPE_WRAPPER, world);
|
|
||||||
|
|
||||||
if (type == Type.BLASTING) {
|
|
||||||
RECIPE_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<? extends AbstractCookingRecipe> smeltingRecipe = world.getRecipeManager()
|
|
||||||
.getRecipeFor(RecipeType.SMELTING, RECIPE_WRAPPER, world);
|
|
||||||
if (!smeltingRecipe.isPresent()) {
|
|
||||||
RECIPE_WRAPPER.setItem(0, stack);
|
|
||||||
smeltingRecipe = world.getRecipeManager()
|
|
||||||
.getRecipeFor(RecipeType.BLASTING, RECIPE_WRAPPER, world);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (smeltingRecipe.isPresent()) {
|
|
||||||
RegistryAccess registryAccess = world.registryAccess();
|
|
||||||
if (smokingRecipe.isEmpty() || !ItemStack.isSameItem(smokingRecipe.get()
|
|
||||||
.getResultItem(registryAccess),
|
|
||||||
smeltingRecipe.get()
|
|
||||||
.getResultItem(registryAccess))) {
|
|
||||||
return RecipeApplier.applyRecipeOn(world, stack, smeltingRecipe.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == Type.SMOKING && smokingRecipe.isPresent())
|
|
||||||
return RecipeApplier.applyRecipeOn(world, stack, smokingRecipe.get());
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int decrementProcessingTime(ItemEntity entity, Type type) {
|
|
||||||
CompoundTag nbt = entity.getPersistentData();
|
|
||||||
|
|
||||||
if (!nbt.contains("CreateData"))
|
|
||||||
nbt.put("CreateData", new CompoundTag());
|
|
||||||
CompoundTag createData = nbt.getCompound("CreateData");
|
|
||||||
|
|
||||||
if (!createData.contains("Processing"))
|
|
||||||
createData.put("Processing", new CompoundTag());
|
|
||||||
CompoundTag processing = createData.getCompound("Processing");
|
|
||||||
|
|
||||||
if (!processing.contains("Type") || Type.valueOf(processing.getString("Type")) != type) {
|
|
||||||
processing.putString("Type", type.name());
|
|
||||||
int timeModifierForStackSize = ((entity.getItem()
|
|
||||||
.getCount() - 1) / 16) + 1;
|
|
||||||
int processingTime =
|
|
||||||
(int) (AllConfigs.server().kinetics.fanProcessingTime.get() * timeModifierForStackSize) + 1;
|
|
||||||
processing.putInt("Time", processingTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
int value = processing.getInt("Time") - 1;
|
|
||||||
processing.putInt("Time", value);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum Type {
|
|
||||||
SPLASHING {
|
|
||||||
@Override
|
|
||||||
public void spawnParticlesForProcessing(Level level, Vec3 pos) {
|
|
||||||
if (level.random.nextInt(8) != 0)
|
|
||||||
return;
|
|
||||||
Vector3f color = new Color(0x0055FF).asVectorF();
|
|
||||||
level.addParticle(new DustParticleOptions(color, 1), pos.x + (level.random.nextFloat() - .5f) * .5f,
|
|
||||||
pos.y + .5f, pos.z + (level.random.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
|
||||||
level.addParticle(ParticleTypes.SPIT, pos.x + (level.random.nextFloat() - .5f) * .5f, pos.y + .5f,
|
|
||||||
pos.z + (level.random.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void affectEntity(Entity entity, Level level) {
|
|
||||||
if (level.isClientSide)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (entity instanceof EnderMan || entity.getType() == EntityType.SNOW_GOLEM
|
|
||||||
|| entity.getType() == EntityType.BLAZE) {
|
|
||||||
entity.hurt(entity.damageSources().drown(), 2);
|
|
||||||
}
|
|
||||||
if (entity.isOnFire()) {
|
|
||||||
entity.clearFire();
|
|
||||||
level.playSound(null, entity.blockPosition(), SoundEvents.GENERIC_EXTINGUISH_FIRE,
|
|
||||||
SoundSource.NEUTRAL, 0.7F, 1.6F + (level.random.nextFloat() - level.random.nextFloat()) * 0.4F);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProcess(ItemStack stack, Level level) {
|
|
||||||
return isWashable(stack, level);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
SMOKING {
|
|
||||||
@Override
|
|
||||||
public void spawnParticlesForProcessing(Level level, Vec3 pos) {
|
|
||||||
if (level.random.nextInt(8) != 0)
|
|
||||||
return;
|
|
||||||
level.addParticle(ParticleTypes.POOF, pos.x, pos.y + .25f, pos.z, 0, 1 / 16f, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void affectEntity(Entity entity, Level level) {
|
|
||||||
if (level.isClientSide)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!entity.fireImmune()) {
|
|
||||||
entity.setSecondsOnFire(2);
|
|
||||||
entity.hurt(AllDamageTypes.FAN_FIRE.source(level), 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProcess(ItemStack stack, Level level) {
|
|
||||||
RECIPE_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<SmokingRecipe> recipe = level.getRecipeManager()
|
|
||||||
.getRecipeFor(RecipeType.SMOKING, RECIPE_WRAPPER, level);
|
|
||||||
return recipe.isPresent();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
HAUNTING {
|
|
||||||
@Override
|
|
||||||
public void spawnParticlesForProcessing(Level level, Vec3 pos) {
|
|
||||||
if (level.random.nextInt(8) != 0)
|
|
||||||
return;
|
|
||||||
pos = pos.add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1)
|
|
||||||
.multiply(1, 0.05f, 1)
|
|
||||||
.normalize()
|
|
||||||
.scale(0.15f));
|
|
||||||
level.addParticle(ParticleTypes.SOUL_FIRE_FLAME, pos.x, pos.y + .45f, pos.z, 0, 0, 0);
|
|
||||||
if (level.random.nextInt(2) == 0)
|
|
||||||
level.addParticle(ParticleTypes.SMOKE, pos.x, pos.y + .25f, pos.z, 0, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void affectEntity(Entity entity, Level level) {
|
|
||||||
if (level.isClientSide) {
|
|
||||||
if (entity instanceof Horse) {
|
|
||||||
Vec3 p = entity.getPosition(0);
|
|
||||||
Vec3 v = p.add(0, 0.5f, 0)
|
|
||||||
.add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1)
|
|
||||||
.multiply(1, 0.2f, 1)
|
|
||||||
.normalize()
|
|
||||||
.scale(1f));
|
|
||||||
level.addParticle(ParticleTypes.SOUL_FIRE_FLAME, v.x, v.y, v.z, 0, 0.1f, 0);
|
|
||||||
if (level.random.nextInt(3) == 0)
|
|
||||||
level.addParticle(ParticleTypes.LARGE_SMOKE, p.x, p.y + .5f, p.z,
|
|
||||||
(level.random.nextFloat() - .5f) * .5f, 0.1f, (level.random.nextFloat() - .5f) * .5f);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entity instanceof LivingEntity livingEntity) {
|
|
||||||
livingEntity.addEffect(new MobEffectInstance(MobEffects.BLINDNESS, 30, 0, false, false));
|
|
||||||
livingEntity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 20, 1, false, false));
|
|
||||||
}
|
|
||||||
if (entity instanceof Horse horse) {
|
|
||||||
int progress = horse.getPersistentData()
|
|
||||||
.getInt("CreateHaunting");
|
|
||||||
if (progress < 100) {
|
|
||||||
if (progress % 10 == 0) {
|
|
||||||
level.playSound(null, entity.blockPosition(), SoundEvents.SOUL_ESCAPE, SoundSource.NEUTRAL,
|
|
||||||
1f, 1.5f * progress / 100f);
|
|
||||||
}
|
|
||||||
horse.getPersistentData()
|
|
||||||
.putInt("CreateHaunting", progress + 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
level.playSound(null, entity.blockPosition(), SoundEvents.GENERIC_EXTINGUISH_FIRE,
|
|
||||||
SoundSource.NEUTRAL, 1.25f, 0.65f);
|
|
||||||
|
|
||||||
SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(level);
|
|
||||||
CompoundTag serializeNBT = horse.saveWithoutId(new CompoundTag());
|
|
||||||
serializeNBT.remove("UUID");
|
|
||||||
if (!horse.getArmor()
|
|
||||||
.isEmpty())
|
|
||||||
horse.spawnAtLocation(horse.getArmor());
|
|
||||||
|
|
||||||
skeletonHorse.deserializeNBT(serializeNBT);
|
|
||||||
skeletonHorse.setPos(horse.getPosition(0));
|
|
||||||
level.addFreshEntity(skeletonHorse);
|
|
||||||
horse.discard();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProcess(ItemStack stack, Level level) {
|
|
||||||
return isHauntable(stack, level);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
BLASTING {
|
|
||||||
@Override
|
|
||||||
public void spawnParticlesForProcessing(Level level, Vec3 pos) {
|
|
||||||
if (level.random.nextInt(8) != 0)
|
|
||||||
return;
|
|
||||||
level.addParticle(ParticleTypes.LARGE_SMOKE, pos.x, pos.y + .25f, pos.z, 0, 1 / 16f, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void affectEntity(Entity entity, Level level) {
|
|
||||||
if (level.isClientSide)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!entity.fireImmune()) {
|
|
||||||
entity.setSecondsOnFire(10);
|
|
||||||
entity.hurt(AllDamageTypes.FAN_LAVA.source(level), 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProcess(ItemStack stack, Level level) {
|
|
||||||
RECIPE_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<SmeltingRecipe> smeltingRecipe = level.getRecipeManager()
|
|
||||||
.getRecipeFor(RecipeType.SMELTING, RECIPE_WRAPPER, level);
|
|
||||||
|
|
||||||
if (smeltingRecipe.isPresent())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
RECIPE_WRAPPER.setItem(0, stack);
|
|
||||||
Optional<BlastingRecipe> blastingRecipe = level.getRecipeManager()
|
|
||||||
.getRecipeFor(RecipeType.BLASTING, RECIPE_WRAPPER, level);
|
|
||||||
|
|
||||||
if (blastingRecipe.isPresent())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return !stack.getItem()
|
|
||||||
.isFireResistant();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
NONE {
|
|
||||||
@Override
|
|
||||||
public void spawnParticlesForProcessing(Level level, Vec3 pos) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void affectEntity(Entity entity, Level level) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canProcess(ItemStack stack, Level level) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public abstract boolean canProcess(ItemStack stack, Level level);
|
|
||||||
|
|
||||||
public abstract void spawnParticlesForProcessing(Level level, Vec3 pos);
|
|
||||||
|
|
||||||
public abstract void affectEntity(Entity entity, Level level);
|
|
||||||
|
|
||||||
public static Type byBlock(BlockGetter reader, BlockPos pos) {
|
|
||||||
FluidState fluidState = reader.getFluidState(pos);
|
|
||||||
if (fluidState.getType() == Fluids.WATER || fluidState.getType() == Fluids.FLOWING_WATER)
|
|
||||||
return Type.SPLASHING;
|
|
||||||
BlockState blockState = reader.getBlockState(pos);
|
|
||||||
Block block = blockState.getBlock();
|
|
||||||
if (block == Blocks.SOUL_FIRE
|
|
||||||
|| block == Blocks.SOUL_CAMPFIRE && blockState.getOptionalValue(CampfireBlock.LIT)
|
|
||||||
.orElse(false)
|
|
||||||
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
|
||||||
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
|
|
||||||
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.SOUL)
|
|
||||||
.orElse(false))
|
|
||||||
return Type.HAUNTING;
|
|
||||||
if (block == Blocks.FIRE
|
|
||||||
|| blockState.is(BlockTags.CAMPFIRES) && blockState.getOptionalValue(CampfireBlock.LIT)
|
|
||||||
.orElse(false)
|
|
||||||
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
|
||||||
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
|
|
||||||
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.REGULAR)
|
|
||||||
.orElse(false)
|
|
||||||
|| getHeatLevelOf(blockState) == BlazeBurnerBlock.HeatLevel.SMOULDERING)
|
|
||||||
return Type.SMOKING;
|
|
||||||
if (block == Blocks.LAVA || getHeatLevelOf(blockState).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING))
|
|
||||||
return Type.BLASTING;
|
|
||||||
return Type.NONE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SplashingWrapper extends RecipeWrapper {
|
|
||||||
public SplashingWrapper() {
|
|
||||||
super(new ItemStackHandler(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class HauntingWrapper extends RecipeWrapper {
|
|
||||||
public HauntingWrapper() {
|
|
||||||
super(new ItemStackHandler(1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,486 @@
|
||||||
|
package com.simibubi.create.content.kinetics.fan.processing;
|
||||||
|
|
||||||
|
import static com.simibubi.create.content.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllBlocks;
|
||||||
|
import com.simibubi.create.AllDamageTypes;
|
||||||
|
import com.simibubi.create.AllRecipeTypes;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe.HauntingWrapper;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe.SplashingWrapper;
|
||||||
|
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||||
|
import com.simibubi.create.content.processing.burner.LitBlazeBurnerBlock;
|
||||||
|
import com.simibubi.create.foundation.recipe.RecipeApplier;
|
||||||
|
import com.simibubi.create.foundation.utility.Color;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.RegistryAccess;
|
||||||
|
import net.minecraft.core.particles.BlockParticleOption;
|
||||||
|
import net.minecraft.core.particles.DustParticleOptions;
|
||||||
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.sounds.SoundEvents;
|
||||||
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
import net.minecraft.tags.BlockTags;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.effect.MobEffectInstance;
|
||||||
|
import net.minecraft.world.effect.MobEffects;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
import net.minecraft.world.entity.LivingEntity;
|
||||||
|
import net.minecraft.world.entity.animal.horse.Horse;
|
||||||
|
import net.minecraft.world.entity.animal.horse.SkeletonHorse;
|
||||||
|
import net.minecraft.world.entity.monster.EnderMan;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.item.crafting.AbstractCookingRecipe;
|
||||||
|
import net.minecraft.world.item.crafting.BlastingRecipe;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeType;
|
||||||
|
import net.minecraft.world.item.crafting.SmeltingRecipe;
|
||||||
|
import net.minecraft.world.item.crafting.SmokingRecipe;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.Blocks;
|
||||||
|
import net.minecraft.world.level.block.CampfireBlock;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.material.Fluid;
|
||||||
|
import net.minecraft.world.level.material.FluidState;
|
||||||
|
import net.minecraft.world.level.material.Fluids;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||||
|
|
||||||
|
public class AllFanProcessingTypes {
|
||||||
|
public static final NoneType NONE = register("none", new NoneType());
|
||||||
|
public static final BlastingType BLASTING = register("blasting", new BlastingType());
|
||||||
|
public static final HauntingType HAUNTING = register("haunting", new HauntingType());
|
||||||
|
public static final SmokingType SMOKING = register("smoking", new SmokingType());
|
||||||
|
public static final SplashingType SPLASHING = register("splashing", new SplashingType());
|
||||||
|
|
||||||
|
private static final Map<String, FanProcessingType> LEGACY_NAME_MAP;
|
||||||
|
|
||||||
|
static {
|
||||||
|
Object2ReferenceOpenHashMap<String, FanProcessingType> map = new Object2ReferenceOpenHashMap<>();
|
||||||
|
map.put("NONE", NONE);
|
||||||
|
map.put("BLASTING", BLASTING);
|
||||||
|
map.put("HAUNTING", HAUNTING);
|
||||||
|
map.put("SMOKING", SMOKING);
|
||||||
|
map.put("SPLASHING", SPLASHING);
|
||||||
|
map.trim();
|
||||||
|
LEGACY_NAME_MAP = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static <T extends FanProcessingType> T register(String id, T type) {
|
||||||
|
FanProcessingTypeRegistry.register(Create.asResource(id), type);
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static FanProcessingType ofLegacyName(String name) {
|
||||||
|
return LEGACY_NAME_MAP.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void register() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FanProcessingType parseLegacy(String str) {
|
||||||
|
FanProcessingType type = ofLegacyName(str);
|
||||||
|
if (type != null) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
return FanProcessingType.parse(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class NoneType implements FanProcessingType {
|
||||||
|
@Override
|
||||||
|
public boolean isValidAt(Level level, BlockPos pos) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return -1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProcess(ItemStack stack, Level level) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<ItemStack> process(ItemStack stack, Level level) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnProcessingParticles(Level level, Vec3 pos) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void morphAirFlow(AirFlowParticleAccess particleAccess, RandomSource random) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void affectEntity(Entity entity, Level level) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BlastingType implements FanProcessingType {
|
||||||
|
private static final RecipeWrapper RECIPE_WRAPPER = new RecipeWrapper(new ItemStackHandler(1));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidAt(Level level, BlockPos pos) {
|
||||||
|
BlockState blockState = level.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
return block == Blocks.LAVA || getHeatLevelOf(blockState).isAtLeast(BlazeBurnerBlock.HeatLevel.FADING);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProcess(ItemStack stack, Level level) {
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<SmeltingRecipe> smeltingRecipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.SMELTING, RECIPE_WRAPPER, level);
|
||||||
|
|
||||||
|
if (smeltingRecipe.isPresent())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<BlastingRecipe> blastingRecipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.BLASTING, RECIPE_WRAPPER, level);
|
||||||
|
|
||||||
|
if (blastingRecipe.isPresent())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return !stack.getItem()
|
||||||
|
.isFireResistant();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<ItemStack> process(ItemStack stack, Level level) {
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<SmokingRecipe> smokingRecipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.SMOKING, RECIPE_WRAPPER, level);
|
||||||
|
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<? extends AbstractCookingRecipe> smeltingRecipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.SMELTING, RECIPE_WRAPPER, level);
|
||||||
|
if (!smeltingRecipe.isPresent()) {
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
smeltingRecipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.BLASTING, RECIPE_WRAPPER, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (smeltingRecipe.isPresent()) {
|
||||||
|
RegistryAccess registryAccess = level.registryAccess();
|
||||||
|
if (!smokingRecipe.isPresent() || !ItemStack.isSameItem(smokingRecipe.get()
|
||||||
|
.getResultItem(registryAccess),
|
||||||
|
smeltingRecipe.get()
|
||||||
|
.getResultItem(registryAccess))) {
|
||||||
|
return RecipeApplier.applyRecipeOn(level, stack, smeltingRecipe.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnProcessingParticles(Level level, Vec3 pos) {
|
||||||
|
if (level.random.nextInt(8) != 0)
|
||||||
|
return;
|
||||||
|
level.addParticle(ParticleTypes.LARGE_SMOKE, pos.x, pos.y + .25f, pos.z, 0, 1 / 16f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void morphAirFlow(AirFlowParticleAccess particleAccess, RandomSource random) {
|
||||||
|
particleAccess.setColor(Color.mixColors(0xFF4400, 0xFF8855, random.nextFloat()));
|
||||||
|
particleAccess.setAlpha(.5f);
|
||||||
|
if (random.nextFloat() < 1 / 32f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.FLAME, .25f);
|
||||||
|
if (random.nextFloat() < 1 / 16f)
|
||||||
|
particleAccess.spawnExtraParticle(new BlockParticleOption(ParticleTypes.BLOCK, Blocks.LAVA.defaultBlockState()), .25f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void affectEntity(Entity entity, Level level) {
|
||||||
|
if (level.isClientSide)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!entity.fireImmune()) {
|
||||||
|
entity.setSecondsOnFire(10);
|
||||||
|
entity.hurt(AllDamageTypes.FAN_LAVA.source(level), 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class HauntingType implements FanProcessingType {
|
||||||
|
private static final HauntingWrapper HAUNTING_WRAPPER = new HauntingWrapper();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidAt(Level level, BlockPos pos) {
|
||||||
|
BlockState blockState = level.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
return block == Blocks.SOUL_FIRE
|
||||||
|
|| block == Blocks.SOUL_CAMPFIRE && blockState.getOptionalValue(CampfireBlock.LIT)
|
||||||
|
.orElse(false)
|
||||||
|
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
||||||
|
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
|
||||||
|
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.SOUL)
|
||||||
|
.orElse(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProcess(ItemStack stack, Level level) {
|
||||||
|
HAUNTING_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(HAUNTING_WRAPPER, level);
|
||||||
|
return recipe.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<ItemStack> process(ItemStack stack, Level level) {
|
||||||
|
HAUNTING_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(HAUNTING_WRAPPER, level);
|
||||||
|
if (recipe.isPresent())
|
||||||
|
return RecipeApplier.applyRecipeOn(level, stack, recipe.get());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnProcessingParticles(Level level, Vec3 pos) {
|
||||||
|
if (level.random.nextInt(8) != 0)
|
||||||
|
return;
|
||||||
|
pos = pos.add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1)
|
||||||
|
.multiply(1, 0.05f, 1)
|
||||||
|
.normalize()
|
||||||
|
.scale(0.15f));
|
||||||
|
level.addParticle(ParticleTypes.SOUL_FIRE_FLAME, pos.x, pos.y + .45f, pos.z, 0, 0, 0);
|
||||||
|
if (level.random.nextInt(2) == 0)
|
||||||
|
level.addParticle(ParticleTypes.SMOKE, pos.x, pos.y + .25f, pos.z, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void morphAirFlow(AirFlowParticleAccess particleAccess, RandomSource random) {
|
||||||
|
particleAccess.setColor(Color.mixColors(0x0, 0x126568, random.nextFloat()));
|
||||||
|
particleAccess.setAlpha(1f);
|
||||||
|
if (random.nextFloat() < 1 / 128f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.SOUL_FIRE_FLAME, .125f);
|
||||||
|
if (random.nextFloat() < 1 / 32f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.SMOKE, .125f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void affectEntity(Entity entity, Level level) {
|
||||||
|
if (level.isClientSide) {
|
||||||
|
if (entity instanceof Horse) {
|
||||||
|
Vec3 p = entity.getPosition(0);
|
||||||
|
Vec3 v = p.add(0, 0.5f, 0)
|
||||||
|
.add(VecHelper.offsetRandomly(Vec3.ZERO, level.random, 1)
|
||||||
|
.multiply(1, 0.2f, 1)
|
||||||
|
.normalize()
|
||||||
|
.scale(1f));
|
||||||
|
level.addParticle(ParticleTypes.SOUL_FIRE_FLAME, v.x, v.y, v.z, 0, 0.1f, 0);
|
||||||
|
if (level.random.nextInt(3) == 0)
|
||||||
|
level.addParticle(ParticleTypes.LARGE_SMOKE, p.x, p.y + .5f, p.z,
|
||||||
|
(level.random.nextFloat() - .5f) * .5f, 0.1f, (level.random.nextFloat() - .5f) * .5f);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entity instanceof LivingEntity livingEntity) {
|
||||||
|
livingEntity.addEffect(new MobEffectInstance(MobEffects.BLINDNESS, 30, 0, false, false));
|
||||||
|
livingEntity.addEffect(new MobEffectInstance(MobEffects.MOVEMENT_SLOWDOWN, 20, 1, false, false));
|
||||||
|
}
|
||||||
|
if (entity instanceof Horse horse) {
|
||||||
|
int progress = horse.getPersistentData()
|
||||||
|
.getInt("CreateHaunting");
|
||||||
|
if (progress < 100) {
|
||||||
|
if (progress % 10 == 0) {
|
||||||
|
level.playSound(null, entity.blockPosition(), SoundEvents.SOUL_ESCAPE, SoundSource.NEUTRAL,
|
||||||
|
1f, 1.5f * progress / 100f);
|
||||||
|
}
|
||||||
|
horse.getPersistentData()
|
||||||
|
.putInt("CreateHaunting", progress + 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
level.playSound(null, entity.blockPosition(), SoundEvents.GENERIC_EXTINGUISH_FIRE,
|
||||||
|
SoundSource.NEUTRAL, 1.25f, 0.65f);
|
||||||
|
|
||||||
|
SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(level);
|
||||||
|
CompoundTag serializeNBT = horse.saveWithoutId(new CompoundTag());
|
||||||
|
serializeNBT.remove("UUID");
|
||||||
|
if (!horse.getArmor()
|
||||||
|
.isEmpty())
|
||||||
|
horse.spawnAtLocation(horse.getArmor());
|
||||||
|
|
||||||
|
skeletonHorse.deserializeNBT(serializeNBT);
|
||||||
|
skeletonHorse.setPos(horse.getPosition(0));
|
||||||
|
level.addFreshEntity(skeletonHorse);
|
||||||
|
horse.discard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SmokingType implements FanProcessingType {
|
||||||
|
private static final RecipeWrapper RECIPE_WRAPPER = new RecipeWrapper(new ItemStackHandler(1));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidAt(Level level, BlockPos pos) {
|
||||||
|
BlockState blockState = level.getBlockState(pos);
|
||||||
|
Block block = blockState.getBlock();
|
||||||
|
return block == Blocks.FIRE
|
||||||
|
|| blockState.is(BlockTags.CAMPFIRES) && blockState.getOptionalValue(CampfireBlock.LIT)
|
||||||
|
.orElse(false)
|
||||||
|
|| AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
||||||
|
&& blockState.getOptionalValue(LitBlazeBurnerBlock.FLAME_TYPE)
|
||||||
|
.map(flame -> flame == LitBlazeBurnerBlock.FlameType.REGULAR)
|
||||||
|
.orElse(false)
|
||||||
|
|| getHeatLevelOf(blockState) == BlazeBurnerBlock.HeatLevel.SMOULDERING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProcess(ItemStack stack, Level level) {
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<SmokingRecipe> recipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.SMOKING, RECIPE_WRAPPER, level);
|
||||||
|
return recipe.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<ItemStack> process(ItemStack stack, Level level) {
|
||||||
|
RECIPE_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<SmokingRecipe> smokingRecipe = level.getRecipeManager()
|
||||||
|
.getRecipeFor(RecipeType.SMOKING, RECIPE_WRAPPER, level);
|
||||||
|
|
||||||
|
if (smokingRecipe.isPresent())
|
||||||
|
return RecipeApplier.applyRecipeOn(level, stack, smokingRecipe.get());
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnProcessingParticles(Level level, Vec3 pos) {
|
||||||
|
if (level.random.nextInt(8) != 0)
|
||||||
|
return;
|
||||||
|
level.addParticle(ParticleTypes.POOF, pos.x, pos.y + .25f, pos.z, 0, 1 / 16f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void morphAirFlow(AirFlowParticleAccess particleAccess, RandomSource random) {
|
||||||
|
particleAccess.setColor(Color.mixColors(0x0, 0x555555, random.nextFloat()));
|
||||||
|
particleAccess.setAlpha(1f);
|
||||||
|
if (random.nextFloat() < 1 / 32f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.SMOKE, .125f);
|
||||||
|
if (random.nextFloat() < 1 / 32f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.LARGE_SMOKE, .125f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void affectEntity(Entity entity, Level level) {
|
||||||
|
if (level.isClientSide)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!entity.fireImmune()) {
|
||||||
|
entity.setSecondsOnFire(2);
|
||||||
|
entity.hurt(AllDamageTypes.FAN_FIRE.source(level), 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SplashingType implements FanProcessingType {
|
||||||
|
private static final SplashingWrapper SPLASHING_WRAPPER = new SplashingWrapper();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValidAt(Level level, BlockPos pos) {
|
||||||
|
FluidState fluidState = level.getFluidState(pos);
|
||||||
|
Fluid fluid = fluidState.getType();
|
||||||
|
return fluid == Fluids.WATER || fluid == Fluids.FLOWING_WATER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canProcess(ItemStack stack, Level level) {
|
||||||
|
SPLASHING_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<SplashingRecipe> recipe = AllRecipeTypes.SPLASHING.find(SPLASHING_WRAPPER, level);
|
||||||
|
return recipe.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public List<ItemStack> process(ItemStack stack, Level level) {
|
||||||
|
SPLASHING_WRAPPER.setItem(0, stack);
|
||||||
|
Optional<SplashingRecipe> recipe = AllRecipeTypes.SPLASHING.find(SPLASHING_WRAPPER, level);
|
||||||
|
if (recipe.isPresent())
|
||||||
|
return RecipeApplier.applyRecipeOn(level, stack, recipe.get());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void spawnProcessingParticles(Level level, Vec3 pos) {
|
||||||
|
if (level.random.nextInt(8) != 0)
|
||||||
|
return;
|
||||||
|
Vector3f color = new Color(0x0055FF).asVectorF();
|
||||||
|
level.addParticle(new DustParticleOptions(color, 1), pos.x + (level.random.nextFloat() - .5f) * .5f,
|
||||||
|
pos.y + .5f, pos.z + (level.random.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
||||||
|
level.addParticle(ParticleTypes.SPIT, pos.x + (level.random.nextFloat() - .5f) * .5f, pos.y + .5f,
|
||||||
|
pos.z + (level.random.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void morphAirFlow(AirFlowParticleAccess particleAccess, RandomSource random) {
|
||||||
|
particleAccess.setColor(Color.mixColors(0x4499FF, 0x2277FF, random.nextFloat()));
|
||||||
|
particleAccess.setAlpha(1f);
|
||||||
|
if (random.nextFloat() < 1 / 32f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.BUBBLE, .125f);
|
||||||
|
if (random.nextFloat() < 1 / 32f)
|
||||||
|
particleAccess.spawnExtraParticle(ParticleTypes.BUBBLE_POP, .125f);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void affectEntity(Entity entity, Level level) {
|
||||||
|
if (level.isClientSide)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (entity instanceof EnderMan || entity.getType() == EntityType.SNOW_GOLEM
|
||||||
|
|| entity.getType() == EntityType.BLAZE) {
|
||||||
|
entity.hurt(entity.damageSources().drown(), 2);
|
||||||
|
}
|
||||||
|
if (entity.isOnFire()) {
|
||||||
|
entity.clearFire();
|
||||||
|
level.playSound(null, entity.blockPosition(), SoundEvents.GENERIC_EXTINGUISH_FIRE,
|
||||||
|
SoundSource.NEUTRAL, 0.7F, 1.6F + (level.random.nextFloat() - level.random.nextFloat()) * 0.4F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
package com.simibubi.create.content.kinetics.fan.processing;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.kinetics.belt.behaviour.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||||
|
import com.simibubi.create.content.kinetics.belt.transport.TransportedItemStack;
|
||||||
|
import com.simibubi.create.infrastructure.config.AllConfigs;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
|
||||||
|
public class FanProcessing {
|
||||||
|
public static boolean canProcess(ItemEntity entity, FanProcessingType type) {
|
||||||
|
if (entity.getPersistentData()
|
||||||
|
.contains("CreateData")) {
|
||||||
|
CompoundTag compound = entity.getPersistentData()
|
||||||
|
.getCompound("CreateData");
|
||||||
|
if (compound.contains("Processing")) {
|
||||||
|
CompoundTag processing = compound.getCompound("Processing");
|
||||||
|
|
||||||
|
if (AllFanProcessingTypes.parseLegacy(processing.getString("Type")) != type)
|
||||||
|
return type.canProcess(entity.getItem(), entity.level());
|
||||||
|
else if (processing.getInt("Time") >= 0)
|
||||||
|
return true;
|
||||||
|
else if (processing.getInt("Time") == -1)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return type.canProcess(entity.getItem(), entity.level());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean applyProcessing(ItemEntity entity, FanProcessingType type) {
|
||||||
|
if (decrementProcessingTime(entity, type) != 0)
|
||||||
|
return false;
|
||||||
|
List<ItemStack> stacks = type.process(entity.getItem(), entity.level());
|
||||||
|
if (stacks == null)
|
||||||
|
return false;
|
||||||
|
if (stacks.isEmpty()) {
|
||||||
|
entity.discard();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
entity.setItem(stacks.remove(0));
|
||||||
|
for (ItemStack additional : stacks) {
|
||||||
|
ItemEntity entityIn = new ItemEntity(entity.level(), entity.getX(), entity.getY(), entity.getZ(), additional);
|
||||||
|
entityIn.setDeltaMovement(entity.getDeltaMovement());
|
||||||
|
entity.level().addFreshEntity(entityIn);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TransportedResult applyProcessing(TransportedItemStack transported, Level world, FanProcessingType type) {
|
||||||
|
TransportedResult ignore = TransportedResult.doNothing();
|
||||||
|
if (transported.processedBy != type) {
|
||||||
|
transported.processedBy = type;
|
||||||
|
int timeModifierForStackSize = ((transported.stack.getCount() - 1) / 16) + 1;
|
||||||
|
int processingTime =
|
||||||
|
(int) (AllConfigs.server().kinetics.fanProcessingTime.get() * timeModifierForStackSize) + 1;
|
||||||
|
transported.processingTime = processingTime;
|
||||||
|
if (!type.canProcess(transported.stack, world))
|
||||||
|
transported.processingTime = -1;
|
||||||
|
return ignore;
|
||||||
|
}
|
||||||
|
if (transported.processingTime == -1)
|
||||||
|
return ignore;
|
||||||
|
if (transported.processingTime-- > 0)
|
||||||
|
return ignore;
|
||||||
|
|
||||||
|
List<ItemStack> stacks = type.process(transported.stack, world);
|
||||||
|
if (stacks == null)
|
||||||
|
return ignore;
|
||||||
|
|
||||||
|
List<TransportedItemStack> transportedStacks = new ArrayList<>();
|
||||||
|
for (ItemStack additional : stacks) {
|
||||||
|
TransportedItemStack newTransported = transported.getSimilar();
|
||||||
|
newTransported.stack = additional.copy();
|
||||||
|
transportedStacks.add(newTransported);
|
||||||
|
}
|
||||||
|
return TransportedResult.convertTo(transportedStacks);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int decrementProcessingTime(ItemEntity entity, FanProcessingType type) {
|
||||||
|
CompoundTag nbt = entity.getPersistentData();
|
||||||
|
|
||||||
|
if (!nbt.contains("CreateData"))
|
||||||
|
nbt.put("CreateData", new CompoundTag());
|
||||||
|
CompoundTag createData = nbt.getCompound("CreateData");
|
||||||
|
|
||||||
|
if (!createData.contains("Processing"))
|
||||||
|
createData.put("Processing", new CompoundTag());
|
||||||
|
CompoundTag processing = createData.getCompound("Processing");
|
||||||
|
|
||||||
|
if (!processing.contains("Type") || AllFanProcessingTypes.parseLegacy(processing.getString("Type")) != type) {
|
||||||
|
processing.putString("Type", FanProcessingTypeRegistry.getIdOrThrow(type).toString());
|
||||||
|
int timeModifierForStackSize = ((entity.getItem()
|
||||||
|
.getCount() - 1) / 16) + 1;
|
||||||
|
int processingTime =
|
||||||
|
(int) (AllConfigs.server().kinetics.fanProcessingTime.get() * timeModifierForStackSize) + 1;
|
||||||
|
processing.putInt("Time", processingTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
int value = processing.getInt("Time") - 1;
|
||||||
|
processing.putInt("Time", value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.simibubi.create.content.kinetics.fan.processing;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.particles.ParticleOptions;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
import net.minecraft.util.RandomSource;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
import net.minecraft.world.item.ItemStack;
|
||||||
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public interface FanProcessingType {
|
||||||
|
boolean isValidAt(Level level, BlockPos pos);
|
||||||
|
|
||||||
|
int getPriority();
|
||||||
|
|
||||||
|
boolean canProcess(ItemStack stack, Level level);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
List<ItemStack> process(ItemStack stack, Level level);
|
||||||
|
|
||||||
|
void spawnProcessingParticles(Level level, Vec3 pos);
|
||||||
|
|
||||||
|
void morphAirFlow(AirFlowParticleAccess particleAccess, RandomSource random);
|
||||||
|
|
||||||
|
void affectEntity(Entity entity, Level level);
|
||||||
|
|
||||||
|
static FanProcessingType parse(String str) {
|
||||||
|
ResourceLocation id = ResourceLocation.tryParse(str);
|
||||||
|
if (id == null) {
|
||||||
|
return AllFanProcessingTypes.NONE;
|
||||||
|
}
|
||||||
|
FanProcessingType type = FanProcessingTypeRegistry.getType(id);
|
||||||
|
if (type == null) {
|
||||||
|
return AllFanProcessingTypes.NONE;
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static FanProcessingType getAt(Level level, BlockPos pos) {
|
||||||
|
for (FanProcessingType type : FanProcessingTypeRegistry.getSortedTypesView()) {
|
||||||
|
if (type.isValidAt(level, pos)) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return AllFanProcessingTypes.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AirFlowParticleAccess {
|
||||||
|
void setColor(int color);
|
||||||
|
|
||||||
|
void setAlpha(float alpha);
|
||||||
|
|
||||||
|
void spawnExtraParticle(ParticleOptions options, float speedMultiplier);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.simibubi.create.content.kinetics.fan.processing;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
|
||||||
|
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
public class FanProcessingTypeRegistry {
|
||||||
|
private static final Map<ResourceLocation, FanProcessingType> TYPES = new Object2ReferenceOpenHashMap<>();
|
||||||
|
private static final Map<FanProcessingType, ResourceLocation> IDS = new Reference2ObjectOpenHashMap<>();
|
||||||
|
private static final List<FanProcessingType> SORTED_TYPES = new ReferenceArrayList<>();
|
||||||
|
private static final List<FanProcessingType> SORTED_TYPES_VIEW = Collections.unmodifiableList(SORTED_TYPES);
|
||||||
|
|
||||||
|
public static void register(ResourceLocation id, FanProcessingType type) {
|
||||||
|
if (TYPES.put(id, type) != null) {
|
||||||
|
throw new IllegalArgumentException("Tried to override FanProcessingType registration for id '" + id + "'. This is not supported!");
|
||||||
|
}
|
||||||
|
ResourceLocation prevId = IDS.put(type, id);
|
||||||
|
if (prevId != null) {
|
||||||
|
throw new IllegalArgumentException("Tried to register same FanProcessingType instance for multiple ids '" + prevId + "' and '" + id + "'. This is not supported!");
|
||||||
|
}
|
||||||
|
insertSortedType(type, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void insertSortedType(FanProcessingType type, ResourceLocation id) {
|
||||||
|
int index = Collections.binarySearch(SORTED_TYPES, type, (type1, type2) -> type2.getPriority() - type1.getPriority());
|
||||||
|
if (index >= 0) {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
SORTED_TYPES.add(-index - 1, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static FanProcessingType getType(ResourceLocation id) {
|
||||||
|
return TYPES.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static FanProcessingType getTypeOrThrow(ResourceLocation id) {
|
||||||
|
FanProcessingType type = getType(id);
|
||||||
|
if (type == null) {
|
||||||
|
throw new IllegalArgumentException("Could not get FanProcessingType for id '" + id + "'!");
|
||||||
|
}
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ResourceLocation getId(FanProcessingType type) {
|
||||||
|
return IDS.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResourceLocation getIdOrThrow(FanProcessingType type) {
|
||||||
|
ResourceLocation id = getId(type);
|
||||||
|
if (id == null) {
|
||||||
|
throw new IllegalArgumentException("Could not get id for FanProcessingType " + type + "!");
|
||||||
|
}
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<FanProcessingType> getSortedTypesView() {
|
||||||
|
return SORTED_TYPES_VIEW;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,22 +1,25 @@
|
||||||
package com.simibubi.create.content.kinetics.fan;
|
package com.simibubi.create.content.kinetics.fan.processing;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import com.simibubi.create.AllRecipeTypes;
|
import com.simibubi.create.AllRecipeTypes;
|
||||||
|
import com.simibubi.create.content.kinetics.fan.processing.HauntingRecipe.HauntingWrapper;
|
||||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
|
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
|
||||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeParams;
|
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeParams;
|
||||||
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class HauntingRecipe extends ProcessingRecipe<FanProcessing.HauntingWrapper> {
|
public class HauntingRecipe extends ProcessingRecipe<HauntingWrapper> {
|
||||||
|
|
||||||
public HauntingRecipe(ProcessingRecipeParams params) {
|
public HauntingRecipe(ProcessingRecipeParams params) {
|
||||||
super(AllRecipeTypes.HAUNTING, params);
|
super(AllRecipeTypes.HAUNTING, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(FanProcessing.HauntingWrapper inv, Level worldIn) {
|
public boolean matches(HauntingWrapper inv, Level worldIn) {
|
||||||
if (inv.isEmpty())
|
if (inv.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
return ingredients.get(0)
|
return ingredients.get(0)
|
||||||
|
@ -33,4 +36,10 @@ public class HauntingRecipe extends ProcessingRecipe<FanProcessing.HauntingWrapp
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class HauntingWrapper extends RecipeWrapper {
|
||||||
|
public HauntingWrapper() {
|
||||||
|
super(new ItemStackHandler(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,16 +1,18 @@
|
||||||
package com.simibubi.create.content.kinetics.fan;
|
package com.simibubi.create.content.kinetics.fan.processing;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
import com.simibubi.create.AllRecipeTypes;
|
import com.simibubi.create.AllRecipeTypes;
|
||||||
import com.simibubi.create.content.kinetics.fan.FanProcessing.SplashingWrapper;
|
import com.simibubi.create.content.kinetics.fan.processing.SplashingRecipe.SplashingWrapper;
|
||||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
|
import com.simibubi.create.content.processing.recipe.ProcessingRecipe;
|
||||||
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeParams;
|
import com.simibubi.create.content.processing.recipe.ProcessingRecipeBuilder.ProcessingRecipeParams;
|
||||||
|
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraftforge.items.ItemStackHandler;
|
||||||
|
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
public class SplashingRecipe extends ProcessingRecipe<FanProcessing.SplashingWrapper> {
|
public class SplashingRecipe extends ProcessingRecipe<SplashingWrapper> {
|
||||||
|
|
||||||
public SplashingRecipe(ProcessingRecipeParams params) {
|
public SplashingRecipe(ProcessingRecipeParams params) {
|
||||||
super(AllRecipeTypes.SPLASHING, params);
|
super(AllRecipeTypes.SPLASHING, params);
|
||||||
|
@ -34,4 +36,10 @@ public class SplashingRecipe extends ProcessingRecipe<FanProcessing.SplashingWra
|
||||||
return 12;
|
return 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SplashingWrapper extends RecipeWrapper {
|
||||||
|
public SplashingWrapper() {
|
||||||
|
super(new ItemStackHandler(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -47,6 +47,11 @@ public class CuttingRecipe extends ProcessingRecipe<RecipeWrapper> implements IA
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canSpecifyDuration() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addAssemblyIngredients(List<Ingredient> list) {}
|
public void addAssemblyIngredients(List<Ingredient> list) {}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ import net.minecraft.core.Direction.Axis;
|
||||||
import net.minecraft.core.Direction.AxisDirection;
|
import net.minecraft.core.Direction.AxisDirection;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.content.kinetics.transmission.sequencer;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
import com.simibubi.create.AllPackets;
|
import com.simibubi.create.AllPackets;
|
||||||
import com.simibubi.create.compat.computercraft.ComputerScreen;
|
import com.simibubi.create.compat.computercraft.ComputerScreen;
|
||||||
|
|
|
@ -18,7 +18,6 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.Direction.Axis;
|
import net.minecraft.core.Direction.Axis;
|
||||||
import net.minecraft.world.InteractionHand;
|
import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.entity.item.ItemEntity;
|
import net.minecraft.world.entity.item.ItemEntity;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
|
|
|
@ -13,7 +13,7 @@ import org.apache.commons.lang3.StringUtils;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.simibubi.create.AllRecipeTypes;
|
import com.simibubi.create.AllRecipeTypes;
|
||||||
import com.simibubi.create.content.kinetics.fan.FanProcessing;
|
import com.simibubi.create.content.kinetics.fan.processing.AllFanProcessingTypes;
|
||||||
import com.simibubi.create.content.logistics.filter.attribute.BookAuthorAttribute;
|
import com.simibubi.create.content.logistics.filter.attribute.BookAuthorAttribute;
|
||||||
import com.simibubi.create.content.logistics.filter.attribute.BookCopyAttribute;
|
import com.simibubi.create.content.logistics.filter.attribute.BookCopyAttribute;
|
||||||
import com.simibubi.create.content.logistics.filter.attribute.ColorAttribute;
|
import com.simibubi.create.content.logistics.filter.attribute.ColorAttribute;
|
||||||
|
@ -143,8 +143,8 @@ public interface ItemAttribute {
|
||||||
EQUIPABLE(s -> LivingEntity.getEquipmentSlotForItem(s)
|
EQUIPABLE(s -> LivingEntity.getEquipmentSlotForItem(s)
|
||||||
.getType() != EquipmentSlot.Type.HAND),
|
.getType() != EquipmentSlot.Type.HAND),
|
||||||
FURNACE_FUEL(AbstractFurnaceBlockEntity::isFuel),
|
FURNACE_FUEL(AbstractFurnaceBlockEntity::isFuel),
|
||||||
WASHABLE(FanProcessing::isWashable),
|
WASHABLE(AllFanProcessingTypes.SPLASHING::canProcess),
|
||||||
HAUNTABLE(FanProcessing::isHauntable),
|
HAUNTABLE(AllFanProcessingTypes.HAUNTING::canProcess),
|
||||||
CRUSHABLE((s, w) -> testRecipe(s, w, AllRecipeTypes.CRUSHING.getType())
|
CRUSHABLE((s, w) -> testRecipe(s, w, AllRecipeTypes.CRUSHING.getType())
|
||||||
|| testRecipe(s, w, AllRecipeTypes.MILLING.getType())),
|
|| testRecipe(s, w, AllRecipeTypes.MILLING.getType())),
|
||||||
SMELTABLE((s, w) -> testRecipe(s, w, RecipeType.SMELTING)),
|
SMELTABLE((s, w) -> testRecipe(s, w, RecipeType.SMELTING)),
|
||||||
|
|
|
@ -210,6 +210,11 @@ public class BasinRecipe extends ProcessingRecipe<SmartInventory> {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean canSpecifyDuration() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(SmartInventory inv, @Nonnull Level worldIn) {
|
public boolean matches(SmartInventory inv, @Nonnull Level worldIn) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -72,7 +72,7 @@ public abstract class ProcessingRecipe<T extends Container> implements Recipe<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean canSpecifyDuration() {
|
protected boolean canSpecifyDuration() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected int getMaxFluidInputCount() {
|
protected int getMaxFluidInputCount() {
|
||||||
|
|
|
@ -237,10 +237,10 @@ public class AllDisplayBehaviours {
|
||||||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
||||||
DisplayBehaviour computerDisplaySource = register(Create.asResource("computer_display_source"), new ComputerDisplaySource());
|
DisplayBehaviour computerDisplaySource = register(Create.asResource("computer_display_source"), new ComputerDisplaySource());
|
||||||
|
|
||||||
assignBlockEntity(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "wired_modem_full"));
|
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("wired_modem_full"));
|
||||||
assignBlockEntity(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_normal"));
|
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_normal"));
|
||||||
assignBlockEntity(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_advanced"));
|
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_advanced"));
|
||||||
assignBlockEntity(computerDisplaySource, new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_command"));
|
assignBlockEntity(computerDisplaySource, Mods.COMPUTERCRAFT.rl("computer_command"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,19 +24,13 @@ import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemp
|
||||||
|
|
||||||
public class SchematicInstances {
|
public class SchematicInstances {
|
||||||
|
|
||||||
public static final WorldAttached<Cache<Integer, SchematicWorld>> loadedSchematics;
|
private static final WorldAttached<Cache<Integer, SchematicWorld>> LOADED_SCHEMATICS = new WorldAttached<>($ -> CacheBuilder.newBuilder()
|
||||||
|
|
||||||
static {
|
|
||||||
loadedSchematics = new WorldAttached<>($ -> CacheBuilder.newBuilder()
|
|
||||||
.expireAfterAccess(5, TimeUnit.MINUTES)
|
.expireAfterAccess(5, TimeUnit.MINUTES)
|
||||||
.build());
|
.build());
|
||||||
}
|
|
||||||
|
|
||||||
public static void register() {}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static SchematicWorld get(Level world, ItemStack schematic) {
|
public static SchematicWorld get(Level world, ItemStack schematic) {
|
||||||
Cache<Integer, SchematicWorld> map = loadedSchematics.get(world);
|
Cache<Integer, SchematicWorld> map = LOADED_SCHEMATICS.get(world);
|
||||||
int hash = getHash(schematic);
|
int hash = getHash(schematic);
|
||||||
SchematicWorld ifPresent = map.getIfPresent(hash);
|
SchematicWorld ifPresent = map.getIfPresent(hash);
|
||||||
if (ifPresent != null)
|
if (ifPresent != null)
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.content.schematics.client;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.AllItems;
|
import com.simibubi.create.AllItems;
|
||||||
import com.simibubi.create.CreateClient;
|
import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.simibubi.create.content.trains.bogey;
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
|
|
||||||
import com.simibubi.create.content.trains.entity.CarriageBogey;
|
import com.simibubi.create.content.trains.entity.CarriageBogey;
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
|
|
@ -8,7 +8,6 @@ import static com.simibubi.create.AllPartialModels.LARGE_BOGEY_WHEELS;
|
||||||
import static com.simibubi.create.AllPartialModels.SMALL_BOGEY_WHEELS;
|
import static com.simibubi.create.AllPartialModels.SMALL_BOGEY_WHEELS;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.util.transform.Transform;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
|
|
@ -289,9 +289,9 @@ public class CarriageContraption extends Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<BlockEntity> getSpecialRenderedTEs() {
|
public Collection<BlockEntity> getSpecialRenderedBEs() {
|
||||||
if (notInPortal())
|
if (notInPortal())
|
||||||
return super.getSpecialRenderedTEs();
|
return super.getSpecialRenderedBEs();
|
||||||
return specialRenderedBEsOutsidePortal;
|
return specialRenderedBEsOutsidePortal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.item.context.BlockPlaceContext;
|
import net.minecraft.world.item.context.BlockPlaceContext;
|
||||||
import net.minecraft.world.item.context.UseOnContext;
|
import net.minecraft.world.item.context.UseOnContext;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.SignalGetter;
|
import net.minecraft.world.level.SignalGetter;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.CreateClient;
|
||||||
import com.simibubi.create.content.equipment.blueprint.BlueprintOverlayRenderer;
|
import com.simibubi.create.content.equipment.blueprint.BlueprintOverlayRenderer;
|
||||||
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
||||||
import com.simibubi.create.foundation.utility.AngleHelper;
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||||
import com.simibubi.create.foundation.utility.Couple;
|
import com.simibubi.create.foundation.utility.Couple;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
@ -44,7 +45,6 @@ import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.EntityBlock;
|
import net.minecraft.world.level.block.EntityBlock;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.Property;
|
|
||||||
import net.minecraft.world.phys.BlockHitResult;
|
import net.minecraft.world.phys.BlockHitResult;
|
||||||
import net.minecraft.world.phys.HitResult;
|
import net.minecraft.world.phys.HitResult;
|
||||||
import net.minecraft.world.phys.HitResult.Type;
|
import net.minecraft.world.phys.HitResult.Type;
|
||||||
|
@ -478,18 +478,6 @@ public class TrackPlacement {
|
||||||
info.requiredPavement += TrackPaver.paveCurve(level, info.curve, block, simulate, visited);
|
info.requiredPavement += TrackPaver.paveCurve(level, info.curve, block, simulate, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BlockState copyProperties(BlockState from, BlockState onto) {
|
|
||||||
for (Property property : onto.getProperties()) {
|
|
||||||
if (from.hasProperty(property))
|
|
||||||
onto = onto.setValue(property, from.getValue(property));
|
|
||||||
}
|
|
||||||
return onto;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static BlockState copyProperties(BlockState from, BlockState onto, boolean keepFrom) {
|
|
||||||
return keepFrom ? from : copyProperties(from, onto);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static PlacementInfo placeTracks(Level level, PlacementInfo info, BlockState state1, BlockState state2,
|
private static PlacementInfo placeTracks(Level level, PlacementInfo info, BlockState state1, BlockState state2,
|
||||||
BlockPos targetPos1, BlockPos targetPos2, boolean simulate) {
|
BlockPos targetPos1, BlockPos targetPos2, boolean simulate) {
|
||||||
info.requiredTracks = 0;
|
info.requiredTracks = 0;
|
||||||
|
@ -518,7 +506,7 @@ public class TrackPlacement {
|
||||||
BlockPos offsetPos = pos.offset(BlockPos.containing(offset));
|
BlockPos offsetPos = pos.offset(BlockPos.containing(offset));
|
||||||
BlockState stateAtPos = level.getBlockState(offsetPos);
|
BlockState stateAtPos = level.getBlockState(offsetPos);
|
||||||
// copy over all shared properties from the shaped state to the correct track material block
|
// copy over all shared properties from the shaped state to the correct track material block
|
||||||
BlockState toPlace = copyProperties(state, info.trackMaterial.getBlock().defaultBlockState());
|
BlockState toPlace = BlockHelper.copyProperties(state, info.trackMaterial.getBlock().defaultBlockState());
|
||||||
|
|
||||||
boolean canPlace = stateAtPos.canBeReplaced();
|
boolean canPlace = stateAtPos.canBeReplaced();
|
||||||
if (canPlace)
|
if (canPlace)
|
||||||
|
@ -543,12 +531,12 @@ public class TrackPlacement {
|
||||||
BlockState onto = info.trackMaterial.getBlock().defaultBlockState();
|
BlockState onto = info.trackMaterial.getBlock().defaultBlockState();
|
||||||
BlockState stateAtPos = level.getBlockState(targetPos1);
|
BlockState stateAtPos = level.getBlockState(targetPos1);
|
||||||
level.setBlock(targetPos1, ProperWaterloggedBlock.withWater(level,
|
level.setBlock(targetPos1, ProperWaterloggedBlock.withWater(level,
|
||||||
(AllTags.AllBlockTags.TRACKS.matches(stateAtPos) ? stateAtPos : copyProperties(state1, onto))
|
(AllTags.AllBlockTags.TRACKS.matches(stateAtPos) ? stateAtPos : BlockHelper.copyProperties(state1, onto))
|
||||||
.setValue(TrackBlock.HAS_BE, true), targetPos1), 3);
|
.setValue(TrackBlock.HAS_BE, true), targetPos1), 3);
|
||||||
|
|
||||||
stateAtPos = level.getBlockState(targetPos2);
|
stateAtPos = level.getBlockState(targetPos2);
|
||||||
level.setBlock(targetPos2, ProperWaterloggedBlock.withWater(level,
|
level.setBlock(targetPos2, ProperWaterloggedBlock.withWater(level,
|
||||||
(AllTags.AllBlockTags.TRACKS.matches(stateAtPos) ? stateAtPos : copyProperties(state2, onto))
|
(AllTags.AllBlockTags.TRACKS.matches(stateAtPos) ? stateAtPos : BlockHelper.copyProperties(state2, onto))
|
||||||
.setValue(TrackBlock.HAS_BE, true), targetPos2), 3);
|
.setValue(TrackBlock.HAS_BE, true), targetPos2), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@ import net.minecraft.MethodsReturnNonnullByDefault;
|
||||||
import net.minecraft.advancements.CriterionTrigger;
|
import net.minecraft.advancements.CriterionTrigger;
|
||||||
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance;
|
import net.minecraft.advancements.critereon.AbstractCriterionTriggerInstance;
|
||||||
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
||||||
import net.minecraft.advancements.critereon.EntityPredicate;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.PlayerAdvancements;
|
import net.minecraft.server.PlayerAdvancements;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
|
@ -11,7 +11,6 @@ import com.google.gson.JsonObject;
|
||||||
import net.minecraft.MethodsReturnNonnullByDefault;
|
import net.minecraft.MethodsReturnNonnullByDefault;
|
||||||
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
import net.minecraft.advancements.critereon.ContextAwarePredicate;
|
||||||
import net.minecraft.advancements.critereon.DeserializationContext;
|
import net.minecraft.advancements.critereon.DeserializationContext;
|
||||||
import net.minecraft.advancements.critereon.EntityPredicate;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.server.level.ServerPlayer;
|
import net.minecraft.server.level.ServerPlayer;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import java.util.Optional;
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
import com.mojang.blaze3d.platform.Window;
|
import com.mojang.blaze3d.platform.Window;
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.foundation.config.ui.entries.NumberEntry;
|
import com.simibubi.create.foundation.config.ui.entries.NumberEntry;
|
||||||
import com.simibubi.create.foundation.gui.RemovedGuiUtils;
|
import com.simibubi.create.foundation.gui.RemovedGuiUtils;
|
||||||
import com.simibubi.create.foundation.gui.Theme;
|
import com.simibubi.create.foundation.gui.Theme;
|
||||||
|
|
|
@ -3,19 +3,17 @@ package com.simibubi.create.foundation.damageTypes;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
import com.simibubi.create.AllDamageTypes;
|
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
|
||||||
|
|
||||||
import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllDamageTypes;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
|
||||||
import net.minecraft.core.HolderLookup.Provider;
|
import net.minecraft.core.HolderLookup.Provider;
|
||||||
import net.minecraft.core.RegistrySetBuilder;
|
import net.minecraft.core.RegistrySetBuilder;
|
||||||
import net.minecraft.core.registries.Registries;
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.data.DataProvider;
|
import net.minecraft.data.DataProvider;
|
||||||
import net.minecraft.data.PackOutput;
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraftforge.common.data.DatapackBuiltinEntriesProvider;
|
||||||
|
|
||||||
public class DamageTypeDataProvider extends DatapackBuiltinEntriesProvider {
|
public class DamageTypeDataProvider extends DatapackBuiltinEntriesProvider {
|
||||||
private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder()
|
private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder()
|
||||||
|
|
|
@ -10,7 +10,6 @@ import javax.annotation.Nullable;
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderRegistry;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
|
||||||
import com.simibubi.create.AllBlockEntityTypes;
|
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.tterrag.registrate.AbstractRegistrate;
|
import com.tterrag.registrate.AbstractRegistrate;
|
||||||
import com.tterrag.registrate.builders.BlockEntityBuilder;
|
import com.tterrag.registrate.builders.BlockEntityBuilder;
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.simibubi.create.foundation.data;
|
||||||
|
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllTags.AllRecipeSerializerTags;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.compat.Mods;
|
||||||
|
|
||||||
|
import net.minecraft.core.HolderLookup;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
|
import net.minecraft.data.PackOutput;
|
||||||
|
import net.minecraft.data.tags.TagsProvider;
|
||||||
|
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||||
|
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||||
|
|
||||||
|
public class RecipeSerializerTagGen extends TagsProvider<RecipeSerializer<?>> {
|
||||||
|
public RecipeSerializerTagGen(PackOutput output, CompletableFuture<HolderLookup.Provider> lookupProvider, @Nullable ExistingFileHelper existingFileHelper) {
|
||||||
|
super(output, Registries.RECIPE_SERIALIZER, lookupProvider, Create.ID, existingFileHelper);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "Create's Recipe Serializer Tags";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addTags(HolderLookup.Provider provider) {
|
||||||
|
this.tag(AllRecipeSerializerTags.AUTOMATION_IGNORE.tag)
|
||||||
|
.addOptional(Mods.OCCULTISM.rl("spirit_trade"))
|
||||||
|
.addOptional(Mods.OCCULTISM.rl("ritual"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package com.simibubi.create.foundation.gui;
|
package com.simibubi.create.foundation.gui;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.foundation.gui.element.ScreenElement;
|
import com.simibubi.create.foundation.gui.element.ScreenElement;
|
||||||
import com.simibubi.create.foundation.utility.Color;
|
import com.simibubi.create.foundation.utility.Color;
|
||||||
|
|
|
@ -3,8 +3,6 @@ package com.simibubi.create.foundation.gui.widget;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.simibubi.create.foundation.gui.element.RenderElement;
|
import com.simibubi.create.foundation.gui.element.RenderElement;
|
||||||
import com.simibubi.create.foundation.gui.element.ScreenElement;
|
import com.simibubi.create.foundation.gui.element.ScreenElement;
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.simibubi.create.foundation.gui.widget;
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
import com.simibubi.create.foundation.utility.Components;
|
import com.simibubi.create.foundation.utility.Components;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package com.simibubi.create.foundation.mixin.client;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At.Shift;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
@Mixin(PoseStack.class)
|
|
||||||
public class FixNormalScalingMixin {
|
|
||||||
/**
|
|
||||||
* Minecraft negates the normal matrix if all scales are equal and negative, but
|
|
||||||
* does not return afterward. This allows the rest of the method's logic to be
|
|
||||||
* applied, which negates the matrix again, resulting in the matrix being the
|
|
||||||
* same as in the beginning.
|
|
||||||
*/
|
|
||||||
@Inject(at = @At(value = "INVOKE", target = "Lorg/joml/Matrix3f;scale(F)Lorg/joml/Matrix3f;", shift = Shift.AFTER, remap = false), method = "scale(FFF)V", cancellable = true)
|
|
||||||
private void create$returnAfterNegate(float x, float y, float z, CallbackInfo ci) {
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minecraft takes the inverse cube root of the product of all scales to provide a
|
|
||||||
* rough estimate for normalization so that it does not need to be done later. It
|
|
||||||
* does not make sense for this "normalization factor" to be negative though, as
|
|
||||||
* that would invert all normals. Additionally, Minecraft's fastInverseCbrt method
|
|
||||||
* does not work for negative numbers.
|
|
||||||
*/
|
|
||||||
@ModifyArg(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;fastInvCubeRoot(F)F"), method = "scale(FFF)V")
|
|
||||||
private float create$absInvCbrtInput(float input) {
|
|
||||||
return Math.abs(input);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
package com.simibubi.create.foundation.ponder;
|
package com.simibubi.create.foundation.ponder;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
import com.simibubi.create.foundation.gui.element.GuiGameElement;
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
package com.simibubi.create.foundation.utility;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraftforge.registries.IForgeRegistry;
|
|
||||||
|
|
||||||
public class CreateRegistry<K, V> {
|
|
||||||
private static final List<CreateRegistry<?, ?>> ALL = new ArrayList<>();
|
|
||||||
|
|
||||||
protected final IForgeRegistry<K> objectRegistry;
|
|
||||||
protected final Map<ResourceLocation, V> locationMap = new HashMap<>();
|
|
||||||
protected final Map<K, V> objectMap = new IdentityHashMap<>();
|
|
||||||
protected boolean unwrapped = false;
|
|
||||||
|
|
||||||
public CreateRegistry(IForgeRegistry<K> objectRegistry) {
|
|
||||||
this.objectRegistry = objectRegistry;
|
|
||||||
ALL.add(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(ResourceLocation location, V value) {
|
|
||||||
if (!unwrapped) {
|
|
||||||
locationMap.put(location, value);
|
|
||||||
} else {
|
|
||||||
K object = objectRegistry.getValue(location);
|
|
||||||
if (object != null) {
|
|
||||||
objectMap.put(object, value);
|
|
||||||
} else {
|
|
||||||
Create.LOGGER.warn("Could not get object for location '" + location + "' in CreateRegistry after unwrapping!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void register(K object, V value) {
|
|
||||||
if (unwrapped) {
|
|
||||||
objectMap.put(object, value);
|
|
||||||
} else {
|
|
||||||
ResourceLocation location = objectRegistry.getKey(object);
|
|
||||||
if (location != null) {
|
|
||||||
locationMap.put(location, value);
|
|
||||||
} else {
|
|
||||||
Create.LOGGER.warn("Could not get location of object '" + object + "' in CreateRegistry before unwrapping!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public V get(ResourceLocation location) {
|
|
||||||
if (!unwrapped) {
|
|
||||||
return locationMap.get(location);
|
|
||||||
} else {
|
|
||||||
K object = objectRegistry.getValue(location);
|
|
||||||
if (object != null) {
|
|
||||||
return objectMap.get(object);
|
|
||||||
} else {
|
|
||||||
Create.LOGGER.warn("Could not get object for location '" + location + "' in CreateRegistry after unwrapping!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public V get(K object) {
|
|
||||||
if (unwrapped) {
|
|
||||||
return objectMap.get(object);
|
|
||||||
} else {
|
|
||||||
ResourceLocation location = objectRegistry.getKey(object);
|
|
||||||
if (location != null) {
|
|
||||||
return locationMap.get(location);
|
|
||||||
} else {
|
|
||||||
Create.LOGGER.warn("Could not get location of object '" + object + "' in CreateRegistry before unwrapping!");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isUnwrapped() {
|
|
||||||
return unwrapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void unwrap() {
|
|
||||||
for (Map.Entry<ResourceLocation, V> entry : locationMap.entrySet()) {
|
|
||||||
ResourceLocation location = entry.getKey();
|
|
||||||
K object = objectRegistry.getValue(location);
|
|
||||||
if (object != null) {
|
|
||||||
objectMap.put(object, entry.getValue());
|
|
||||||
} else {
|
|
||||||
Create.LOGGER.warn("Could not get object for location '" + location + "' in CreateRegistry during unwrapping!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unwrapped = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void unwrapAll() {
|
|
||||||
for (CreateRegistry<?, ?> registry : ALL) {
|
|
||||||
registry.unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,8 +24,8 @@ import net.minecraft.core.Direction;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import net.minecraft.util.RandomSource;
|
import net.minecraft.util.RandomSource;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
import net.minecraftforge.client.model.data.ModelData;
|
||||||
|
|
||||||
public abstract class GhostBlockRenderer {
|
public abstract class GhostBlockRenderer {
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ public class CKinetics extends ConfigBase {
|
||||||
public final ConfigGroup contraptions = group(1, "contraptions", "Moving Contraptions");
|
public final ConfigGroup contraptions = group(1, "contraptions", "Moving Contraptions");
|
||||||
public final ConfigInt maxBlocksMoved = i(2048, 1, "maxBlocksMoved", Comments.maxBlocksMoved);
|
public final ConfigInt maxBlocksMoved = i(2048, 1, "maxBlocksMoved", Comments.maxBlocksMoved);
|
||||||
public final ConfigInt maxDataSize =
|
public final ConfigInt maxDataSize =
|
||||||
i(ContraptionData.DEFAULT_MAX, 0, "maxDataSize", Comments.bytes, Comments.maxDataDisable, Comments.maxDataSize, Comments.maxDataSize2);
|
i(ContraptionData.DEFAULT_LIMIT, 0, "maxDataSize", Comments.bytes, Comments.maxDataDisable, Comments.maxDataSize, Comments.maxDataSize2);
|
||||||
public final ConfigInt maxChassisRange = i(16, 1, "maxChassisRange", Comments.maxChassisRange);
|
public final ConfigInt maxChassisRange = i(16, 1, "maxChassisRange", Comments.maxChassisRange);
|
||||||
public final ConfigInt maxPistonPoles = i(64, 1, "maxPistonPoles", Comments.maxPistonPoles);
|
public final ConfigInt maxPistonPoles = i(64, 1, "maxPistonPoles", Comments.maxPistonPoles);
|
||||||
public final ConfigInt maxRopeLength = i(256, 1, "maxRopeLength", Comments.maxRopeLength);
|
public final ConfigInt maxRopeLength = i(256, 1, "maxRopeLength", Comments.maxRopeLength);
|
||||||
|
|
|
@ -5,21 +5,17 @@ import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.Contraption;
|
|
||||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement;
|
|
||||||
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovingInteraction;
|
|
||||||
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
|
||||||
import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity;
|
|
||||||
|
|
||||||
import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity;
|
|
||||||
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlockEntityTypes;
|
import com.simibubi.create.AllBlockEntityTypes;
|
||||||
|
import com.simibubi.create.content.contraptions.Contraption;
|
||||||
|
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovement;
|
||||||
|
import com.simibubi.create.content.contraptions.actors.contraptionControls.ContraptionControlsMovingInteraction;
|
||||||
|
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
|
||||||
|
import com.simibubi.create.content.kinetics.gauge.SpeedGaugeBlockEntity;
|
||||||
|
import com.simibubi.create.content.kinetics.gauge.StressGaugeBlockEntity;
|
||||||
import com.simibubi.create.content.logistics.tunnel.BrassTunnelBlockEntity.SelectionMode;
|
import com.simibubi.create.content.logistics.tunnel.BrassTunnelBlockEntity.SelectionMode;
|
||||||
import com.simibubi.create.content.redstone.nixieTube.NixieTubeBlockEntity;
|
import com.simibubi.create.content.redstone.nixieTube.NixieTubeBlockEntity;
|
||||||
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||||
|
|
|
@ -14,7 +14,6 @@ import com.simibubi.create.infrastructure.gametest.CreateGameTestHelper;
|
||||||
import com.simibubi.create.infrastructure.gametest.GameTestGroup;
|
import com.simibubi.create.infrastructure.gametest.GameTestGroup;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.gametest.framework.GameTest;
|
import net.minecraft.gametest.framework.GameTest;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
|
|
@ -21,7 +21,6 @@ import com.simibubi.create.infrastructure.gametest.GameTestGroup;
|
||||||
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
import it.unimi.dsi.fastutil.objects.Object2LongMap;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.registries.Registries;
|
|
||||||
import net.minecraft.gametest.framework.GameTest;
|
import net.minecraft.gametest.framework.GameTest;
|
||||||
import net.minecraft.network.chat.MutableComponent;
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
import net.minecraft.world.item.EnchantedBookItem;
|
import net.minecraft.world.item.EnchantedBookItem;
|
||||||
|
|
|
@ -22,7 +22,6 @@ import com.simibubi.create.foundation.utility.Lang;
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.Util;
|
import net.minecraft.Util;
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.gui.GuiGraphics;
|
import net.minecraft.client.gui.GuiGraphics;
|
||||||
import net.minecraft.client.gui.components.Button;
|
import net.minecraft.client.gui.components.Button;
|
||||||
import net.minecraft.client.gui.components.Tooltip;
|
import net.minecraft.client.gui.components.Tooltip;
|
||||||
|
|
|
@ -7,7 +7,6 @@ import com.simibubi.create.compat.Mods;
|
||||||
import com.simibubi.create.foundation.ponder.PonderRegistry;
|
import com.simibubi.create.foundation.ponder.PonderRegistry;
|
||||||
import com.simibubi.create.foundation.ponder.PonderTag;
|
import com.simibubi.create.foundation.ponder.PonderTag;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.item.DyeColor;
|
import net.minecraft.world.item.DyeColor;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
import net.minecraft.world.level.block.Block;
|
import net.minecraft.world.level.block.Block;
|
||||||
|
@ -314,7 +313,7 @@ public class AllPonderTags {
|
||||||
.add(Blocks.TARGET);
|
.add(Blocks.TARGET);
|
||||||
|
|
||||||
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
Mods.COMPUTERCRAFT.executeIfInstalled(() -> () -> {
|
||||||
Block computer = ForgeRegistries.BLOCKS.getValue(new ResourceLocation(Mods.COMPUTERCRAFT.asId(), "computer_advanced"));
|
Block computer = ForgeRegistries.BLOCKS.getValue(Mods.COMPUTERCRAFT.rl("computer_advanced"));
|
||||||
if (computer != null)
|
if (computer != null)
|
||||||
PonderRegistry.TAGS.forTag(DISPLAY_SOURCES).add(computer);
|
PonderRegistry.TAGS.forTag(DISPLAY_SOURCES).add(computer);
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,6 @@ Technology that empowers the player.'''
|
||||||
[[dependencies.create]]
|
[[dependencies.create]]
|
||||||
modId="flywheel"
|
modId="flywheel"
|
||||||
mandatory=true
|
mandatory=true
|
||||||
versionRange="[0.6.9,0.6.10)"
|
versionRange="[0.6.10,0.6.11)"
|
||||||
ordering="AFTER"
|
ordering="AFTER"
|
||||||
side="CLIENT"
|
side="CLIENT"
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
"client.BlockDestructionProgressMixin",
|
"client.BlockDestructionProgressMixin",
|
||||||
"client.CameraMixin",
|
"client.CameraMixin",
|
||||||
"client.EntityContraptionInteractionMixin",
|
"client.EntityContraptionInteractionMixin",
|
||||||
"client.FixNormalScalingMixin",
|
|
||||||
"client.GameRendererMixin",
|
"client.GameRendererMixin",
|
||||||
"client.HeavyBootsOnPlayerMixin",
|
"client.HeavyBootsOnPlayerMixin",
|
||||||
"client.HumanoidArmorLayerMixin",
|
"client.HumanoidArmorLayerMixin",
|
||||||
|
|
|
@ -1,88 +0,0 @@
|
||||||
| Method | Description |
|
|
||||||
|---------------------------------------|------------------------------------------------------|
|
|
||||||
| [`setCursorPos(x, y)`](#setCursorPos) | Sets the cursor position |
|
|
||||||
| [`getCursorPos()`](#getCursorPos) | Gets the current cursor position |
|
|
||||||
| [`getSize()`](#getSize) | Gets the display size of the connected target |
|
|
||||||
| [`isColor()`](#isColor) | Whether the connected display target supports color |
|
|
||||||
| [`isColour()`](#isColour) | Whether the connected display target supports colour |
|
|
||||||
| [`write(text)`](#writetext) | Writes text at the current cursor position |
|
|
||||||
| [`clearLine()`](#clearLine) | Clears the line at the current cursor position |
|
|
||||||
| [`clear()`](#clear) | Clears the whole display |
|
|
||||||
| [`update()`](#update) | Pushes an update to the display target |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `setCursorPos(x, y)`
|
|
||||||
Sets the cursor position. Can be outside the bounds of the connected display.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _x:_ `number` The cursor x position.
|
|
||||||
- _y:_ `number` The cursor y position.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getCursorPos()`
|
|
||||||
Gets the current cursor position.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `number` The cursor x position.
|
|
||||||
- `number` The cursor y position.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getSize()`
|
|
||||||
Gets the size of the connected display target.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `number` The width of the display.
|
|
||||||
- `number` The height of the display.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isColor()`
|
|
||||||
Checks whether the connected display target supports color.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether the display supports color.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isColour()`
|
|
||||||
Checks whether the connected display target supports colour.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether the display supports colour.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `write(text)`
|
|
||||||
Writes text at the current cursor position, moving the cursor to the end of the text.
|
|
||||||
This only writes to an internal buffer. For the changes to show up on the display [`update()`](#update) must be used.
|
|
||||||
If the cursor is outside the bounds of the connected display, the text will not show up on the display.
|
|
||||||
|
|
||||||
This will overwrite any text currently at the cursor position.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _text:_ `string` The text to write.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`update()`](#update) To push the changes to the display target.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `clearLine()`
|
|
||||||
Clears the line at the current cursor position.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`update()`](#update) To push the changes to the display target.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `clear()`
|
|
||||||
Clears the whole display.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`update()`](#update) To push the changes to the display target.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `update()`
|
|
||||||
Pushes any changes to the connected display target.
|
|
||||||
Any changes made are only made to an internal buffer.
|
|
||||||
For them to show up on the display they must be pushed to the display using this function.
|
|
||||||
This allows for this peripheral to be better multithreaded and for users to be able to change multiple lines at once by
|
|
||||||
using multiple [`write(text)`](#writetext) calls and then one [`update()`](#update) call.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`write(text)`](#writetext) To write text to the display target.
|
|
|
@ -1,18 +0,0 @@
|
||||||
| Method | Description |
|
|
||||||
|-------------------------------------------------|----------------------------------------|
|
|
||||||
| [`setTargetSpeed(speed)`](#setTargetSpeedspeed) | Sets the target rotation speed |
|
|
||||||
| [`getTargetSpeed()`](#getTargetSpeed) | Gets the current target rotation speed |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `setTargetSpeed(speed)`
|
|
||||||
Sets the rotation speed controller's target speed.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _speed:_ `number` The target speed in RPM. Must be an integer within the range of [-256..256]. Values outside of this range will be clamped.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getTargetSpeed()`
|
|
||||||
Gets the rotation speed controller's current target speed.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `number` The current target rotation speed in RPM.
|
|
|
@ -1,28 +0,0 @@
|
||||||
| Method | Description |
|
|
||||||
|--------------------------------------------------------|--------------------------------------------------------------|
|
|
||||||
| [`rotate(angle, [modifier])`](#rotateangle-modifier) | Rotates shaft by a set angle |
|
|
||||||
| [`move(distance, [modifier])`](#movedistance-modifier) | Rotates shaft to move Piston/Pulley/Gantry by a set distance |
|
|
||||||
| [`isRunning()`](#isRunning) | Whether the gearshift is currently spinning |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `rotate(angle, [modifier])`
|
|
||||||
Rotates connected components by a set angle.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _angle:_ `number` Angle to rotate the shaft by in degrees. Must be a positive integer. To do backwards rotation, set _modifier_ to a negative value.
|
|
||||||
- _modifier?:_ `number = 1` Speed modifier which can be used to reverse rotation. Must be an integer within the range of [-2..2]. Values out of this range are ignored and the default of 1 is used.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `move(distance, [modifier])`
|
|
||||||
Rotates connected components to move connected piston, pulley or gantry contractions by a set distance.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _distance:_ `number` Distance to move connected piston, pulley or gantry contraptions by. Must be a positive integer. To do backwards movement, set _modifier_ to a negative value.
|
|
||||||
- _modifier?:_ `number = 1` Speed modifier which can be used to reverse direction. Must be an integer within the range of [-2..2]. Values out of this range are ignored and the default of 1 is used.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isRunning()`
|
|
||||||
Checks if the sequenced gearshift is currently spinning.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether the sequenced gearshift is currently spinning.
|
|
|
@ -1,10 +0,0 @@
|
||||||
| Method | Description |
|
|
||||||
|---------------------------|---------------------------------|
|
|
||||||
| [`getSpeed()`](#getSpeed) | Gets the current rotation speed |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getSpeed()`
|
|
||||||
Gets the current rotation speed of the attached components.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `number` The current rotation speed in RPM.
|
|
|
@ -1,18 +0,0 @@
|
||||||
| Method | Description |
|
|
||||||
|---------------------------------------------|--------------------------------|
|
|
||||||
| [`getStress()`](#getStress) | Gets the current stress level |
|
|
||||||
| [`getStressCapacity()`](#getStressCapacity) | Gets the total stress capacity |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getStress()`
|
|
||||||
Gets the connected network's current stress level.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `number` The current stress level in SU.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getStressCapacity()`
|
|
||||||
Gets the connected network's total stress capacity.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `number` The total stress capacity in SU.
|
|
|
@ -1,195 +0,0 @@
|
||||||
Train schedules are represented by a table in Lua. The table contains a list of entries where each entry has a single instruction and multiple conditions.
|
|
||||||
Each instruction and condition has a `data` table that stores specific data about the instruction or condition.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
schedule = {
|
|
||||||
cyclic = true, -- Does the schedule repeat itself after the end has been reached?
|
|
||||||
entries = { -- List of entries, each entry contains a single instruction and multiple conditions.
|
|
||||||
{
|
|
||||||
instruction = {
|
|
||||||
id = "create:destination", -- The different instructions are described below.
|
|
||||||
data = { -- Data that is stored about the instruction. Different for each instruction type.
|
|
||||||
text = "Station 1",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
conditions = { -- List of lists of conditions. The outer list is the "OR" list
|
|
||||||
{ -- and the inner lists are "AND" lists.
|
|
||||||
{
|
|
||||||
id = "create:delay", -- The different conditions are described below.
|
|
||||||
data = { -- Data that is stored about the condition. Different for each condition type.
|
|
||||||
value = 5,
|
|
||||||
time_unit = 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id = "create:powered",
|
|
||||||
data = {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{
|
|
||||||
id = "create:time_of_day",
|
|
||||||
data = {
|
|
||||||
rotation = 0,
|
|
||||||
hour = 14,
|
|
||||||
minute = 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
```
|
|
||||||
---
|
|
||||||
## Instructions
|
|
||||||
| ID | Description |
|
|
||||||
|----------------------------------------------|---------------------------------|
|
|
||||||
| [`"create:destination"`](#createdestination) | Move to a certain train station |
|
|
||||||
| [`"create:rename"`](#createrename) | Change the schedule title |
|
|
||||||
| [`"create:throttle"`](#createthrottle) | Change the train's throttle |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:destination"`
|
|
||||||
Moves the train to the chosen train station. This instruction must have at least one condition.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _text:_ `string` The name of the station to travel to. Can include * as a wildcard.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:rename"`
|
|
||||||
Renames the schedule. This name shows up on display link targets. This instruction cannot have conditions.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _text:_ `string` The name to rename the schedule to.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:throttle"`
|
|
||||||
Changes the throttle of the train. This instruction cannot have conditions.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _value:_ `number` The throttle to set the train to. Must be an integer within the range of [5..100].
|
|
||||||
|
|
||||||
---
|
|
||||||
## Conditions
|
|
||||||
Conditions are stored in a list of lists of conditions. The inner lists contain conditions that get `AND`'ed together. They must all be met for that group to be true.
|
|
||||||
The outer list contains the `AND`'ed groups of conditions that get `OR`'ed together. Only one of the groups needs to be true for the schedule to move onto the next instruction.
|
|
||||||
|
|
||||||
| ID | Description |
|
|
||||||
|-----------------------------------------------------|-----------------------------------------------------|
|
|
||||||
| [`"create:delay"`](#createdelay) | Wait for a certain delay |
|
|
||||||
| [`"create:time_of_day"`](#createtimeofday) | Wait for a specific time of day |
|
|
||||||
| [`"create:fluid_threshold"`](#createfluidthreshold) | Wait for a certain amount of fluid to be on board |
|
|
||||||
| [`"create:item_threshold"`](#createitemthreshold) | Wait for a certain amount of items to be on board |
|
|
||||||
| [`"create:redstone_link"`](#createredstonelink) | Wait for a redstone link to be powered |
|
|
||||||
| [`"create:player_count"`](#createplayercount) | Wait for a certain amount of players to be on board |
|
|
||||||
| [`"create:idle"`](#createidle) | Wait for cargo loading inactivity |
|
|
||||||
| [`"create:unloaded"`](#createunloaded) | Wait for the current chunk to be unloaded |
|
|
||||||
| [`"create:powered"`](#createpowered) | Wait for the station to be powered |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:delay"`
|
|
||||||
Wait for a set delay. Can be measured in ticks, seconds or minutes.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _value:_ `number` The amount of time to wait for.
|
|
||||||
- _time_unit:_ `number` The unit of time. 0 for ticks, 1 for seconds and 2 for minutes.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:time_of_day"`
|
|
||||||
Wait for a time of day, then repeat at a specified interval.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _hour:_ `number` The hour of the day to wait for in a 24-hour format. Must be an integer within the range of [0..23].
|
|
||||||
- _minute:_ `number` The minute of the hour to wait for. Must be an integer within the range of [0..59].
|
|
||||||
- _rotation:_ `number` The interval to repeat at after the time of day has been met. Check the rotation table below for valid values. Must be an integer within the range of [0..9].
|
|
||||||
|
|
||||||
**Rotation**
|
|
||||||
|
|
||||||
| Rotation | Time Interval |
|
|
||||||
|----------|------------------|
|
|
||||||
| 0 | Every Day |
|
|
||||||
| 1 | Every 12 Hours |
|
|
||||||
| 2 | Every 6 Hours |
|
|
||||||
| 3 | Every 4 Hours |
|
|
||||||
| 4 | Every 3 Hours |
|
|
||||||
| 5 | Every 2 Hours |
|
|
||||||
| 6 | Every Hour |
|
|
||||||
| 7 | Every 45 Minutes |
|
|
||||||
| 8 | Every 30 Minutes |
|
|
||||||
| 9 | Every 15 Minutes |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:fluid_threshold"`
|
|
||||||
Wait for a certain amount of a specific fluid to be loaded onto the train.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _bucket:_ `table` The bucket item of the fluid.
|
|
||||||
- _threshold:_ `number` The threshold in number of buckets of fluid. Must be a positive integer.
|
|
||||||
- _operator:_ `number` Whether the condition should wait for the train to be loaded above the threshold, below the threshold or exactly at the threshold. 0 for greater than, 1 for less than, 2 for equal to.
|
|
||||||
- _measure:_ `number` The unit to measure the fluid in. This condition supports buckets as the only unit. Set to 0.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [Items](#items) How items are represented in Lua.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:item_threshold"`
|
|
||||||
Wait for a certain amount of a specific item to be loaded onto the train.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _item:_ `table` The item.
|
|
||||||
- _threshold:_ `number` The threshold of items. Must be a positive integer.
|
|
||||||
- _operator:_ `number` Whether the condition should wait for the train to be loaded above the threshold, below the threshold or exactly at the threshold. 0 for greater than, 1 for less than, 2 for equal to.
|
|
||||||
- _measure:_ `number` The unit to measure the items in. 0 for items. 1 for stacks of items.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [Items](#items) How items are represented in Lua.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:redstone_link"`
|
|
||||||
Wait for a redstone link to be powered.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _frequency:_ `{ table... }` A list of the two items making up the redstone link frequency.
|
|
||||||
- _inverted:_ `number` Whether the redstone link should be powered or not to meet the condition. 0 for powered. 1 for not powered.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [Items](#items) How items are represented in Lua.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:player_count"`
|
|
||||||
Wait for a certain amount of players to be seated on the train.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _count:_ `number` The number of players to be seated on the train. Must be a positive integer.
|
|
||||||
- _exact:_ `number` Whether the seated player count has to be exact to meet the condition. 0 for the exact amount of players seated, 1 for a greater than or equal amount of seated players.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:idle"`
|
|
||||||
Wait for a period of inactivity in loading or unloading the train. Can be measured in ticks, seconds or minutes.
|
|
||||||
|
|
||||||
**Data**
|
|
||||||
- _value:_ `number` The amount of idle time to meet the condition. Must be a positive integer.
|
|
||||||
- _time_unit:_ `number` The unit of time. 0 for ticks, 1 for seconds and 2 for minutes.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:unloaded"`
|
|
||||||
Wait for the chunk the train is in to be unloaded.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `"create:powered"`
|
|
||||||
Wait for the station to be powered with a redstone signal.
|
|
||||||
|
|
||||||
---
|
|
||||||
## Items
|
|
||||||
In Lua, items are represented with an ID and a count.
|
|
||||||
|
|
||||||
```lua
|
|
||||||
item = {
|
|
||||||
id = "minecraft:stone",
|
|
||||||
count = 1,
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
- _id:_ `string` The ID of the item.
|
|
||||||
- _count:_ `number` The amount of items in the stack. For the purposes of working with train schedules the count should always be 1. Must be an integer.
|
|
|
@ -1,179 +0,0 @@
|
||||||
| Method | Description |
|
|
||||||
|-----------------------------------------------------------------|----------------------------------------------------|
|
|
||||||
| [`assemble()`](#assemble) | Assembles a new train at the station |
|
|
||||||
| [`disassemble()`](#disassemble) | Disassembles the currently present train |
|
|
||||||
| [`setAssemblyMode(assemblyMode)`](#setAssemblyModeassemblyMode) | Sets the station's assembly mode |
|
|
||||||
| [`isInAssemblyMode()`](#isInAssemblyMode) | Whether the station is in assembly mode |
|
|
||||||
| [`getStationName()`](#getStationName) | Gets the station's current name |
|
|
||||||
| [`setStationName(name)`](#setStationNamename) | Sets the station's name |
|
|
||||||
| [`isTrainPresent()`](#isTrainPresent) | Whether a train is present at the station |
|
|
||||||
| [`isTrainImminent()`](#isTrainImminent) | Whether a train is imminent to the station |
|
|
||||||
| [`isTrainEnroute()`](#isTrainEnroute) | Whether a train is enroute to the station |
|
|
||||||
| [`getTrainName()`](#getTrainName) | Gets the currently present train's name |
|
|
||||||
| [`setTrainName(name)`](#setTrainNamename) | Sets the currently present train's name |
|
|
||||||
| [`hasSchedule()`](#hasSchedule) | Whether the currently present train has a schedule |
|
|
||||||
| [`getSchedule()`](#getSchedule) | Gets the currently present train's schedule |
|
|
||||||
| [`setSchedule(schedule)`](#setScheduleschedule) | Sets the currently present train's schedule |
|
|
||||||
|
|
||||||
---
|
|
||||||
### `assemble()`
|
|
||||||
Assembles a new train at the station. The station must be in assembly mode prior to calling this function.
|
|
||||||
This function also causes the station to exit assembly mode after the train is done assembing.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not in assembly mode.
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If the train failed to assemble.
|
|
||||||
- If the station failed to exit assembly mode.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`setAssemblyMode(assemblyMode)`](#setAssemblyModeassemblyMode) To set the assembly mode of the station.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `disassemble()`
|
|
||||||
Disassembles the station's currently present train. The station must not be in assembly mode.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is in assembly mode.
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If there is currently no train present at the station.
|
|
||||||
- If the train failed to disassemble.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`setAssemblyMode(assemblyMode)`](#setAssemblyModeassemblyMode) To set the assembly mode of the station.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `setAssemblyMode(assemblyMode)`
|
|
||||||
Sets the station's assembly mode.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _assemblyMode:_ `boolean` Whether the station should be in assembly mode.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station fails to enter or exit assembly mode.
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isInAssemblyMode()`
|
|
||||||
Checks whether the station is in assembly mode.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether the station is in assembly mode.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getStationName()`
|
|
||||||
Gets the station's current name.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `string` The station's current name.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `setStationName(name)`
|
|
||||||
Sets the station's name.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _name:_ `string` What to set the station's name to.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station name fails to be set.
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isTrainPresent()`
|
|
||||||
Checks whether a train is currently present at the station.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether a train is present at the station.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isTrainImminent()`
|
|
||||||
Checks whether a train is imminently arriving at the station.
|
|
||||||
Imminent is defined as being within 30 blocks of the station.
|
|
||||||
This will not be true if the train has arrived and stopped at the station.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether a train is imminent to the station.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [`isTrainPresent()`](#isTrainPresent) To check if a train is present at the station.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `isTrainEnroute()`
|
|
||||||
Checks whether a train is enroute and navigating to the station.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether a train is enroute to the station.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getTrainName()`
|
|
||||||
Gets the currently present train's name.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `string` The currently present train's name.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If there is currently no train present at the station.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `setTrainName(name)`
|
|
||||||
Sets the currently present train's name.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _name:_ `string` What to set the currently present train's name to.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If there is currently no train present at the station.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `hasSchedule()`
|
|
||||||
Checks whether the currently present train has a schedule.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `boolean` Whether the currently present train has a schedule.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If there is currently no train present at the station.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `getSchedule()`
|
|
||||||
Gets the currently present train's schedule.
|
|
||||||
|
|
||||||
**Returns**
|
|
||||||
- `table` The train's schedule
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If there is currently no train present at the station.
|
|
||||||
- If the present train doesn't have a schedule.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [Lua Train Schedules](#Lua-Train-Schedules) How train schedules are represented in Lua.
|
|
||||||
|
|
||||||
---
|
|
||||||
### `setSchedule(schedule)`
|
|
||||||
Sets the currently present train's schedule. This will overwrite the currently set schedule.
|
|
||||||
|
|
||||||
**Parameters**
|
|
||||||
- _schedule:_ `table` The schedule to set the present train to.
|
|
||||||
|
|
||||||
**Throws**
|
|
||||||
- If the station is not connected to a track.
|
|
||||||
- If there is currently no train present at the station.
|
|
||||||
|
|
||||||
**See also**
|
|
||||||
- [Lua Train Schedules](#Lua-Train-Schedules) How train schedules are represented in Lua.
|
|
|
@ -1,2 +0,0 @@
|
||||||
Just before this PR is about to be merged this /wiki folder will be removed from the PR and the pages will be added to
|
|
||||||
the wiki section of the Create GitHub under API Reference
|
|
Loading…
Reference in a new issue