Souls and flames
- Fix lit soul blaze burner providing smoking instead of haunting - Fix horses displaying soul particles even when not being haunted - Add hauntable item attribute - Re-add right clicking lit blaze burner with shovel to extinguish it - Move most fan type functionality to abstract methods in the enum constant - Rework FurnaceEngineModifiers
This commit is contained in:
parent
04c76bb6f0
commit
a666f24ee0
26 changed files with 464 additions and 337 deletions
|
@ -531,21 +531,21 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
f33899d90db924319a1b99065bf1faff1aa40d6a assets/create/lang/en_ud.json
|
||||
748d2635a4f8c97cee2392c1c08c4716f7424202 assets/create/lang/en_us.json
|
||||
d5eed56ff394835dae0f514f9317b83f7fd3954c assets/create/lang/unfinished/de_de.json
|
||||
b44cb66962677538209a02fdafc2e62541542d64 assets/create/lang/unfinished/es_cl.json
|
||||
617f9f1a37b46066b8f6a14f22cbeec8179ce0cd assets/create/lang/unfinished/es_es.json
|
||||
91d391799b6579914ef35cf8ebe917684b25b9df assets/create/lang/unfinished/fr_fr.json
|
||||
787470a30ca417e8cf1da6b47ac40879bb274237 assets/create/lang/unfinished/it_it.json
|
||||
00f079aaebfe906b84b71903f80b0be4127e8cc7 assets/create/lang/unfinished/ja_jp.json
|
||||
75a8b1e3ead980456ff4a4607b1e28197d9de2e8 assets/create/lang/unfinished/ko_kr.json
|
||||
6c7f81042ee0cc25e0ababea6cc254b72557aac9 assets/create/lang/unfinished/nl_nl.json
|
||||
7a3670aa1d488f637a4787c37419a25ace4813bc assets/create/lang/unfinished/pl_pl.json
|
||||
2c30f012946ab67f44514e987e9be87535eb5c5d assets/create/lang/unfinished/pt_br.json
|
||||
d466d2f81d81296313375de4766d4e36d7a5e3e4 assets/create/lang/unfinished/pt_pt.json
|
||||
516e0f0149f814ceec3b15cfb2d46c3c4c8a877c assets/create/lang/unfinished/ru_ru.json
|
||||
d9b421597a5b0b3ae662a12a94c833d853b24fe5 assets/create/lang/unfinished/zh_cn.json
|
||||
68b91bb8f3822d2b0798a6ec8a85d7d188c5c4d1 assets/create/lang/unfinished/zh_tw.json
|
||||
88272181311c543ee6790c7b2d1d434570a5fbad assets/create/lang/en_us.json
|
||||
1b43ebff99b4a65873acc84996b221d17808da82 assets/create/lang/unfinished/de_de.json
|
||||
01f3f59f6007c352addcb6e26afc6c29990e577d assets/create/lang/unfinished/es_cl.json
|
||||
a225447219328491bb5a27c8a4013a627949d86e assets/create/lang/unfinished/es_es.json
|
||||
6b68c9da5fe9b499621e4cfc39c1161d59ceffe1 assets/create/lang/unfinished/fr_fr.json
|
||||
5c1858916d9390961f43d0b0304253e7615d1f60 assets/create/lang/unfinished/it_it.json
|
||||
4e09507f40d2c8c31bc9f0efa105c92a68f091dc assets/create/lang/unfinished/ja_jp.json
|
||||
c3079836f5899cbb39f95e1278cfa1e9b16e2f6c assets/create/lang/unfinished/ko_kr.json
|
||||
2b7bbe3efddf575b13d13944877aff1b9c16bb0a assets/create/lang/unfinished/nl_nl.json
|
||||
51ff37d88dfab3dcc9bd269a651a53c98e5f9fc8 assets/create/lang/unfinished/pl_pl.json
|
||||
23eefb78c4dfd085ad24b48f24203fdd337e221d assets/create/lang/unfinished/pt_br.json
|
||||
b82282978c9213e42b78d5ed86cab3cdc63cb53f assets/create/lang/unfinished/pt_pt.json
|
||||
9b5958c6c7065ff41e9ed74cbe0934910742d39d assets/create/lang/unfinished/ru_ru.json
|
||||
05c401cdcbace483e56e754123922e73ef7e474d assets/create/lang/unfinished/zh_cn.json
|
||||
368a87626c80ddc8aee6aa681e6479fbc06f3716 assets/create/lang/unfinished/zh_tw.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||
|
|
|
@ -1165,6 +1165,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "is not furnace fuel",
|
||||
"create.item_attributes.washable": "can be Washed",
|
||||
"create.item_attributes.washable.inverted": "cannot be Washed",
|
||||
"create.item_attributes.hauntable": "can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "cannot be Haunted",
|
||||
"create.item_attributes.crushable": "can be Crushed",
|
||||
"create.item_attributes.crushable.inverted": "cannot be Crushed",
|
||||
"create.item_attributes.smeltable": "can be Smelted",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1322",
|
||||
"_": "Missing Localizations: 1324",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "ist nicht Brennstoff",
|
||||
"create.item_attributes.washable": "kann gewaschen werden",
|
||||
"create.item_attributes.washable.inverted": "kann nicht gewaschen werden",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "kann zerkleinert werden",
|
||||
"create.item_attributes.crushable.inverted": "kann nicht zerkleinert werden",
|
||||
"create.item_attributes.smeltable": "kann geschmolzen werden",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 333",
|
||||
"_": "Missing Localizations: 335",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "no es cumbustible",
|
||||
"create.item_attributes.washable": "puede Lavarse",
|
||||
"create.item_attributes.washable.inverted": "no puede Lavarse",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "puede ser Triturado",
|
||||
"create.item_attributes.crushable.inverted": "no puede ser Triturado",
|
||||
"create.item_attributes.smeltable": "puede ser Derretido",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 333",
|
||||
"_": "Missing Localizations: 335",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "no es combustible para hornos",
|
||||
"create.item_attributes.washable": "se puede lavar",
|
||||
"create.item_attributes.washable.inverted": "no se puede lavar",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "puede ser molido",
|
||||
"create.item_attributes.crushable.inverted": "no puede ser molido",
|
||||
"create.item_attributes.smeltable": "se puede fundir",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1584",
|
||||
"_": "Missing Localizations: 1586",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "n'est pas un combustible",
|
||||
"create.item_attributes.washable": "peut être lavé",
|
||||
"create.item_attributes.washable.inverted": "ne peut pas être lavé",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "peut être concassé",
|
||||
"create.item_attributes.crushable.inverted": "ne peut pas être concassé",
|
||||
"create.item_attributes.smeltable": "peut être fondu",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1273",
|
||||
"_": "Missing Localizations: 1275",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "non è un combustibile per fornace",
|
||||
"create.item_attributes.washable": "può essere lavato",
|
||||
"create.item_attributes.washable.inverted": "non può essere lavato",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "può essere frantumato",
|
||||
"create.item_attributes.crushable.inverted": "non può essere frantumato",
|
||||
"create.item_attributes.smeltable": "può essere fuso",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 3",
|
||||
"_": "Missing Localizations: 5",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "かまどの燃料でないか",
|
||||
"create.item_attributes.washable": "洗浄できるかか",
|
||||
"create.item_attributes.washable.inverted": "洗浄できないか",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "粉砕できるかか",
|
||||
"create.item_attributes.crushable.inverted": "粉砕できないか",
|
||||
"create.item_attributes.smeltable": "精錬できるかか",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 5",
|
||||
"_": "Missing Localizations: 7",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "화로 연료로 쓸 수 없음",
|
||||
"create.item_attributes.washable": "세척될 수 있음",
|
||||
"create.item_attributes.washable.inverted": "세척될 수 없음",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "분쇄될 수 있음",
|
||||
"create.item_attributes.crushable.inverted": "분쇄될 수 없음",
|
||||
"create.item_attributes.smeltable": "구워질 수 있음",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1937",
|
||||
"_": "Missing Localizations: 1939",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel",
|
||||
"create.item_attributes.washable": "UNLOCALIZED: can be Washed",
|
||||
"create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "UNLOCALIZED: can be Crushed",
|
||||
"create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed",
|
||||
"create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 372",
|
||||
"_": "Missing Localizations: 374",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "nie jest paliwem dla pieca",
|
||||
"create.item_attributes.washable": "może zostać opłukany",
|
||||
"create.item_attributes.washable.inverted": "nie może zostać opłukany",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "może być rozkruszony",
|
||||
"create.item_attributes.crushable.inverted": "nie może być rozkruszony",
|
||||
"create.item_attributes.smeltable": "może zostać przepalony",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1556",
|
||||
"_": "Missing Localizations: 1558",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel",
|
||||
"create.item_attributes.washable": "UNLOCALIZED: can be Washed",
|
||||
"create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "UNLOCALIZED: can be Crushed",
|
||||
"create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed",
|
||||
"create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 1556",
|
||||
"_": "Missing Localizations: 1558",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "UNLOCALIZED: is not furnace fuel",
|
||||
"create.item_attributes.washable": "UNLOCALIZED: can be Washed",
|
||||
"create.item_attributes.washable.inverted": "UNLOCALIZED: cannot be Washed",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "UNLOCALIZED: can be Crushed",
|
||||
"create.item_attributes.crushable.inverted": "UNLOCALIZED: cannot be Crushed",
|
||||
"create.item_attributes.smeltable": "UNLOCALIZED: can be Smelted",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 377",
|
||||
"_": "Missing Localizations: 379",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "не является топливом",
|
||||
"create.item_attributes.washable": "можно промыть",
|
||||
"create.item_attributes.washable.inverted": "нельзя промыть",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "можно измельчить",
|
||||
"create.item_attributes.crushable.inverted": "нельзя разместить",
|
||||
"create.item_attributes.smeltable": "можно расплавить",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 3",
|
||||
"_": "Missing Localizations: 5",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "不可作为燃料",
|
||||
"create.item_attributes.washable": "可被洗涤",
|
||||
"create.item_attributes.washable.inverted": "不可被洗涤",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "可被粉碎",
|
||||
"create.item_attributes.crushable.inverted": "不可被粉碎",
|
||||
"create.item_attributes.smeltable": "可被熔炉烧制",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 391",
|
||||
"_": "Missing Localizations: 393",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -1166,6 +1166,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "不是燃料",
|
||||
"create.item_attributes.washable": "可被篩洗",
|
||||
"create.item_attributes.washable.inverted": "不可被篩洗",
|
||||
"create.item_attributes.hauntable": "UNLOCALIZED: can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "UNLOCALIZED: cannot be Haunted",
|
||||
"create.item_attributes.crushable": "可被粉碎",
|
||||
"create.item_attributes.crushable.inverted": "不可被粉碎",
|
||||
"create.item_attributes.smeltable": "可被熔爐融煉",
|
||||
|
|
|
@ -10,7 +10,7 @@ import com.google.gson.GsonBuilder;
|
|||
import com.simibubi.create.api.behaviour.BlockSpoutingBehaviour;
|
||||
import com.simibubi.create.content.CreateItemGroup;
|
||||
import com.simibubi.create.content.contraptions.TorquePropagator;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineModifiers;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineInteractions;
|
||||
import com.simibubi.create.content.curiosities.weapons.BuiltinPotatoProjectileTypes;
|
||||
import com.simibubi.create.content.logistics.RedstoneLinkNetworkHandler;
|
||||
import com.simibubi.create.content.palettes.AllPaletteBlocks;
|
||||
|
@ -96,8 +96,8 @@ public class Create {
|
|||
AllInteractionBehaviours.register();
|
||||
AllWorldFeatures.register();
|
||||
AllEnchantments.register();
|
||||
FurnaceEngineModifiers.register();
|
||||
AllConfigs.register(modLoadingContext);
|
||||
FurnaceEngineInteractions.registerDefaults();
|
||||
BlockSpoutingBehaviour.register();
|
||||
|
||||
ForgeMod.enableMilkFluid();
|
||||
|
|
|
@ -22,22 +22,11 @@ import net.minecraft.client.Minecraft;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Vec3i;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
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.entity.player.Player;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
@ -53,11 +42,6 @@ import net.minecraftforge.fml.DistExecutor;
|
|||
|
||||
public class AirCurrent {
|
||||
|
||||
private static final DamageSource damageSourceFire = new DamageSource("create.fan_fire").setScalesWithDifficulty()
|
||||
.setIsFire();
|
||||
private static final DamageSource damageSourceLava = new DamageSource("create.fan_lava").setScalesWithDifficulty()
|
||||
.setIsFire();
|
||||
|
||||
public final IAirCurrentSource source;
|
||||
public AABB bounds = new AABB(0, 0, 0, 0, 0, 0);
|
||||
public List<AirCurrentSegment> segments = new ArrayList<>();
|
||||
|
@ -134,93 +118,17 @@ public class AirCurrent {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (entity instanceof ItemEntity) {
|
||||
InWorldProcessing.spawnParticlesForProcessing(world, entity.position(), processingType);
|
||||
ItemEntity itemEntity = (ItemEntity) entity;
|
||||
if (world.isClientSide)
|
||||
if (entity instanceof ItemEntity itemEntity) {
|
||||
if (world.isClientSide) {
|
||||
processingType.spawnParticlesForProcessing(world, entity.position());
|
||||
continue;
|
||||
}
|
||||
if (InWorldProcessing.canProcess(itemEntity, processingType))
|
||||
InWorldProcessing.applyProcessing(itemEntity, processingType);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity instanceof Horse && world.isClientSide) {
|
||||
Vec3 p = entity.getPosition(0);
|
||||
Vec3 v = p.add(0, 0.5f, 0)
|
||||
.add(VecHelper.offsetRandomly(Vec3.ZERO, world.random, 1)
|
||||
.multiply(1, 0.2f, 1)
|
||||
.normalize()
|
||||
.scale(1f));
|
||||
world.addParticle(ParticleTypes.SOUL_FIRE_FLAME, v.x, v.y, v.z, 0, 0.1f, 0);
|
||||
if (world.random.nextInt(3) == 0)
|
||||
world.addParticle(ParticleTypes.LARGE_SMOKE, p.x, p.y + .5f, p.z,
|
||||
(world.random.nextFloat() - .5f) * .5f, 0.1f, (world.random.nextFloat() - .5f) * .5f);
|
||||
}
|
||||
|
||||
if (world.isClientSide)
|
||||
continue;
|
||||
|
||||
switch (processingType) {
|
||||
case BLASTING:
|
||||
if (!entity.fireImmune()) {
|
||||
entity.setSecondsOnFire(10);
|
||||
entity.hurt(damageSourceLava, 4);
|
||||
}
|
||||
break;
|
||||
case SMOKING:
|
||||
if (!entity.fireImmune()) {
|
||||
entity.setSecondsOnFire(2);
|
||||
entity.hurt(damageSourceFire, 2);
|
||||
}
|
||||
break;
|
||||
case HAUNTING:
|
||||
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) {
|
||||
world.playSound(null, entity.blockPosition(), SoundEvents.SOUL_ESCAPE, SoundSource.NEUTRAL,
|
||||
1f, 1.5f * progress / 100f);
|
||||
}
|
||||
horse.getPersistentData()
|
||||
.putInt("CreateHaunting", progress + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
world.playSound(null, entity.blockPosition(), SoundEvents.GENERIC_EXTINGUISH_FIRE,
|
||||
SoundSource.NEUTRAL, 1.25f, 0.65f);
|
||||
|
||||
SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(world);
|
||||
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));
|
||||
world.addFreshEntity(skeletonHorse);
|
||||
horse.discard();
|
||||
}
|
||||
break;
|
||||
case SPLASHING:
|
||||
if (entity instanceof EnderMan || entity.getType() == EntityType.SNOW_GOLEM
|
||||
|| entity.getType() == EntityType.BLAZE) {
|
||||
entity.hurt(DamageSource.DROWN, 2);
|
||||
}
|
||||
if (!entity.isOnFire())
|
||||
break;
|
||||
entity.clearFire();
|
||||
world.playSound(null, entity.blockPosition(), SoundEvents.GENERIC_EXTINGUISH_FIRE, SoundSource.NEUTRAL,
|
||||
0.7F, 1.6F + (world.random.nextFloat() - world.random.nextFloat()) * 0.4F);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
processingType.affectEntity(entity, world);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -375,10 +283,11 @@ public class AirCurrent {
|
|||
InWorldProcessing.Type processingType = pair.getRight();
|
||||
|
||||
handler.handleProcessingOnAllItems((transported) -> {
|
||||
InWorldProcessing.spawnParticlesForProcessing(world, handler.getWorldPositionOf(transported),
|
||||
processingType);
|
||||
if (world.isClientSide)
|
||||
if (world.isClientSide) {
|
||||
if (world != null)
|
||||
processingType.spawnParticlesForProcessing(world, handler.getWorldPositionOf(transported));
|
||||
return TransportedResult.doNothing();
|
||||
}
|
||||
return InWorldProcessing.applyProcessing(transported, world, processingType);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ public class FurnaceEngineBlock extends EngineBlock implements ITE<FurnaceEngine
|
|||
|
||||
@Override
|
||||
protected boolean isValidBaseBlock(BlockState baseBlock, BlockGetter world, BlockPos pos) {
|
||||
return FurnaceEngineModifiers.get().getEngineState(baseBlock).isEngine();
|
||||
return FurnaceEngineInteractions.getHandler(baseBlock).getHeatSource(baseBlock).isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
package com.simibubi.create.content.contraptions.components.flywheel.engine;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.minecraft.world.level.block.AbstractFurnaceBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.registries.IRegistryDelegate;
|
||||
|
||||
/**
|
||||
* Example:
|
||||
*
|
||||
* <pre>
|
||||
* {@code
|
||||
* FurnaceEngineInteractions.registerHandler(Blocks.REDSTONE_LAMP.delegate, FurnaceEngineInteractions.InteractionHandler.of(
|
||||
* s -> s.getBlock() instanceof RedstoneLampBlock && s.hasProperty(RedstoneLampBlock.LIT) ?
|
||||
* (s.getValue(RedstoneLampBlock.LIT) ? HeatSource.ACTIVE : HeatSource.VALID) : HeatSource.EMPTY, s -> 1.5f));
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
public class FurnaceEngineInteractions {
|
||||
|
||||
private static final Map<IRegistryDelegate<Block>, InteractionHandler> HANDLERS = new HashMap<>();
|
||||
private static final InteractionHandler DEFAULT_HANDLER = new InteractionHandler() {};
|
||||
|
||||
public static void registerHandler(IRegistryDelegate<Block> block, InteractionHandler handler) {
|
||||
HANDLERS.put(block, handler);
|
||||
}
|
||||
|
||||
public static InteractionHandler getHandler(IRegistryDelegate<Block> delegate) {
|
||||
return HANDLERS.getOrDefault(delegate, DEFAULT_HANDLER);
|
||||
}
|
||||
|
||||
public static InteractionHandler getHandler(BlockState state) {
|
||||
return getHandler(state.getBlock().delegate);
|
||||
}
|
||||
|
||||
public static void registerDefaults() {
|
||||
registerHandler(Blocks.BLAST_FURNACE.delegate, InteractionHandler.ofCustomSpeedModifier(state -> 2f));
|
||||
}
|
||||
|
||||
public interface InteractionHandler {
|
||||
default HeatSource getHeatSource(BlockState state) {
|
||||
if (state.getBlock() instanceof AbstractFurnaceBlock && state.hasProperty(AbstractFurnaceBlock.LIT)) {
|
||||
if (state.getValue(AbstractFurnaceBlock.LIT)) {
|
||||
return HeatSource.ACTIVE;
|
||||
} else {
|
||||
return HeatSource.VALID;
|
||||
}
|
||||
}
|
||||
return HeatSource.EMPTY;
|
||||
}
|
||||
|
||||
default float getSpeedModifier(BlockState state) {
|
||||
return 1f;
|
||||
};
|
||||
|
||||
static InteractionHandler of(Function<BlockState, HeatSource> heatSourceFunc, Function<BlockState, Float> speedModifierFunc) {
|
||||
return new InteractionHandler() {
|
||||
@Override
|
||||
public HeatSource getHeatSource(BlockState state) {
|
||||
return heatSourceFunc.apply(state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSpeedModifier(BlockState state) {
|
||||
return speedModifierFunc.apply(state);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static InteractionHandler ofCustomHeatSource(Function<BlockState, HeatSource> heatSourceFunc) {
|
||||
return new InteractionHandler() {
|
||||
@Override
|
||||
public HeatSource getHeatSource(BlockState state) {
|
||||
return heatSourceFunc.apply(state);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static InteractionHandler ofCustomSpeedModifier(Function<BlockState, Float> speedModifierFunc) {
|
||||
return new InteractionHandler() {
|
||||
@Override
|
||||
public float getSpeedModifier(BlockState state) {
|
||||
return speedModifierFunc.apply(state);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public enum HeatSource {
|
||||
EMPTY,
|
||||
VALID,
|
||||
ACTIVE;
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this == EMPTY;
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
return this != EMPTY;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this == ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
package com.simibubi.create.content.contraptions.components.flywheel.engine;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import net.minecraft.world.level.block.AbstractFurnaceBlock;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraftforge.registries.IRegistryDelegate;
|
||||
|
||||
public class FurnaceEngineModifiers {
|
||||
|
||||
private final static FurnaceEngineModifiers INSTANCE = new FurnaceEngineModifiers();
|
||||
|
||||
protected FurnaceEngineModifiers() {
|
||||
blockModifiers = new HashMap<>();
|
||||
blockActivators = new HashMap<>();
|
||||
}
|
||||
|
||||
private final Map<IRegistryDelegate<Block>, Float> blockModifiers;
|
||||
private final Map<IRegistryDelegate<Block>, Function<BlockState, EngineState>> blockActivators;
|
||||
|
||||
public void register(IRegistryDelegate<Block> block, float modifier) {
|
||||
this.blockModifiers.put(block, modifier);
|
||||
}
|
||||
|
||||
public void register(IRegistryDelegate<Block> block, float modifier, Function<BlockState, EngineState> engineState) {
|
||||
this.blockModifiers.put(block, modifier);
|
||||
this.blockActivators.put(block, engineState);
|
||||
}
|
||||
|
||||
private float getModifierOrDefault(BlockState state, float defaultValue) {
|
||||
return blockModifiers.getOrDefault(state.getBlock().delegate, defaultValue);
|
||||
}
|
||||
|
||||
private Function<BlockState, EngineState> getEngineStateOrDefault(BlockState state, Function<BlockState, EngineState> engineState) {
|
||||
return blockActivators.getOrDefault(state.getBlock().delegate, engineState);
|
||||
}
|
||||
|
||||
public float getModifier(BlockState state) {
|
||||
return getModifierOrDefault(state, 1f);
|
||||
}
|
||||
|
||||
public EngineState getEngineState(BlockState state) {
|
||||
return getEngineStateOrDefault(state,
|
||||
s -> s.getBlock() instanceof AbstractFurnaceBlock && s.hasProperty(AbstractFurnaceBlock.LIT) ?
|
||||
(s.getValue(AbstractFurnaceBlock.LIT) ? EngineState.ACTIVE : EngineState.VALID) : EngineState.EMPTY).apply(state);
|
||||
}
|
||||
|
||||
public static void register() {
|
||||
get().register(Blocks.BLAST_FURNACE.delegate, 2f);
|
||||
|
||||
/*
|
||||
Example:
|
||||
get().register(Blocks.REDSTONE_LAMP.delegate, 1f,
|
||||
s -> s.getBlock() instanceof RedstoneLampBlock && s.hasProperty(RedstoneLampBlock.LIT) ?
|
||||
(s.getValue(RedstoneLampBlock.LIT) ? EngineState.ACTIVE : EngineState.VALID) : EngineState.EMPTY);
|
||||
*/
|
||||
}
|
||||
|
||||
public static FurnaceEngineModifiers get() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public enum EngineState {
|
||||
EMPTY,
|
||||
VALID,
|
||||
ACTIVE;
|
||||
|
||||
public boolean isEngine() {
|
||||
return this != EMPTY;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return this == ACTIVE;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this == EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
package com.simibubi.create.content.contraptions.components.flywheel.engine;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineModifiers.EngineState;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineInteractions.HeatSource;
|
||||
import com.simibubi.create.content.contraptions.components.flywheel.engine.FurnaceEngineInteractions.InteractionHandler;
|
||||
import com.simibubi.create.foundation.block.BlockStressValues;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -22,12 +23,13 @@ public class FurnaceEngineTileEntity extends EngineTileEntity {
|
|||
|
||||
public void updateFurnace() {
|
||||
BlockState state = level.getBlockState(EngineBlock.getBaseBlockPos(getBlockState(), worldPosition));
|
||||
EngineState engineState = FurnaceEngineModifiers.get().getEngineState(state);
|
||||
if (engineState.isEmpty())
|
||||
InteractionHandler handler = FurnaceEngineInteractions.getHandler(state);
|
||||
HeatSource heatSource = handler.getHeatSource(state);
|
||||
if (heatSource.isEmpty())
|
||||
return;
|
||||
|
||||
float modifier = FurnaceEngineModifiers.get().getModifier(state);
|
||||
boolean active = engineState.isActive();
|
||||
float modifier = handler.getSpeedModifier(state);
|
||||
boolean active = heatSource.isActive();
|
||||
float speed = active ? 16 * modifier : 0;
|
||||
float capacity =
|
||||
(float) (active ? BlockStressValues.getCapacity(AllBlocks.FURNACE_ENGINE.get())
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
package com.simibubi.create.content.contraptions.processing;
|
||||
|
||||
import static com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.mojang.math.Vector3f;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllRecipeTypes;
|
||||
import com.simibubi.create.content.contraptions.components.fan.HauntingRecipe;
|
||||
import com.simibubi.create.content.contraptions.components.fan.SplashingRecipe;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.contraptions.processing.burner.LitBlazeBurnerBlock;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
|
@ -17,10 +25,25 @@ import net.minecraft.core.BlockPos;
|
|||
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.*;
|
||||
import net.minecraft.world.item.crafting.BlastingRecipe;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
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;
|
||||
|
@ -34,44 +57,16 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
|||
import net.minecraftforge.items.ItemStackHandler;
|
||||
import net.minecraftforge.items.wrapper.RecipeWrapper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.getHeatLevelOf;
|
||||
|
||||
public class InWorldProcessing {
|
||||
|
||||
private static final RecipeWrapper WRAPPER = new RecipeWrapper(new ItemStackHandler(1));
|
||||
private static final DamageSource FIRE_DAMAGE_SOURCE = new DamageSource("create.fan_fire").setScalesWithDifficulty()
|
||||
.setIsFire();
|
||||
private static final DamageSource LAVA_DAMAGE_SOURCE = new DamageSource("create.fan_lava").setScalesWithDifficulty()
|
||||
.setIsFire();
|
||||
|
||||
private static final RecipeWrapper RECIPE_WRAPPER = new RecipeWrapper(new ItemStackHandler(1));
|
||||
private static final SplashingWrapper SPLASHING_WRAPPER = new SplashingWrapper();
|
||||
private static final HauntingWrapper SOUL_SMOKING_WRAPPER = new HauntingWrapper();
|
||||
|
||||
public enum Type {
|
||||
SMOKING, BLASTING, SPLASHING, HAUNTING, NONE;
|
||||
|
||||
public static Type byBlock(BlockGetter reader, BlockPos pos) {
|
||||
BlockState blockState = reader.getBlockState(pos);
|
||||
FluidState fluidState = reader.getFluidState(pos);
|
||||
if (fluidState.getType() == Fluids.WATER || fluidState.getType() == Fluids.FLOWING_WATER)
|
||||
return Type.SPLASHING;
|
||||
Block block = blockState.getBlock();
|
||||
if (block == Blocks.SOUL_FIRE
|
||||
|| block == Blocks.SOUL_CAMPFIRE && blockState.getOptionalValue(CampfireBlock.LIT)
|
||||
.orElse(false))
|
||||
return Type.HAUNTING;
|
||||
if (block == Blocks.FIRE || AllBlocks.LIT_BLAZE_BURNER.has(blockState)
|
||||
|| (BlockTags.CAMPFIRES.contains(block) && blockState.getOptionalValue(CampfireBlock.LIT)
|
||||
.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;
|
||||
}
|
||||
}
|
||||
private static final HauntingWrapper HAUNTING_WRAPPER = new HauntingWrapper();
|
||||
|
||||
public static boolean canProcess(ItemEntity entity, Type type) {
|
||||
if (entity.getPersistentData()
|
||||
|
@ -82,7 +77,7 @@ public class InWorldProcessing {
|
|||
CompoundTag processing = compound.getCompound("Processing");
|
||||
|
||||
if (Type.valueOf(processing.getString("Type")) != type) {
|
||||
boolean canProcess = canProcess(entity.getItem(), type, entity.level);
|
||||
boolean canProcess = type.canProcess(entity.getItem(), entity.level);
|
||||
processing.putString("Type", type.name());
|
||||
if (!canProcess)
|
||||
processing.putInt("Time", -1);
|
||||
|
@ -93,43 +88,7 @@ public class InWorldProcessing {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return canProcess(entity.getItem(), type, entity.level);
|
||||
}
|
||||
|
||||
private static boolean canProcess(ItemStack stack, Type type, Level world) {
|
||||
if (type == Type.BLASTING) {
|
||||
WRAPPER.setItem(0, stack);
|
||||
Optional<SmeltingRecipe> smeltingRecipe = world.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.SMELTING, WRAPPER, world);
|
||||
|
||||
if (smeltingRecipe.isPresent())
|
||||
return true;
|
||||
|
||||
WRAPPER.setItem(0, stack);
|
||||
Optional<BlastingRecipe> blastingRecipe = world.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.BLASTING, WRAPPER, world);
|
||||
|
||||
if (blastingRecipe.isPresent())
|
||||
return true;
|
||||
|
||||
return !stack.getItem()
|
||||
.isFireResistant();
|
||||
}
|
||||
|
||||
if (type == Type.SMOKING) {
|
||||
WRAPPER.setItem(0, stack);
|
||||
Optional<SmokingRecipe> recipe = world.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.SMOKING, WRAPPER, world);
|
||||
return recipe.isPresent();
|
||||
}
|
||||
|
||||
if (type == Type.SPLASHING)
|
||||
return isWashable(stack, world);
|
||||
|
||||
if (type == Type.HAUNTING)
|
||||
return isSoulSmokeable(stack, world);
|
||||
|
||||
return false;
|
||||
return type.canProcess(entity.getItem(), entity.level);
|
||||
}
|
||||
|
||||
public static boolean isWashable(ItemStack stack, Level world) {
|
||||
|
@ -138,9 +97,9 @@ public class InWorldProcessing {
|
|||
return recipe.isPresent();
|
||||
}
|
||||
|
||||
public static boolean isSoulSmokeable(ItemStack stack, Level world) {
|
||||
SOUL_SMOKING_WRAPPER.setItem(0, stack);
|
||||
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(SOUL_SMOKING_WRAPPER, world);
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -170,7 +129,7 @@ public class InWorldProcessing {
|
|||
int processingTime =
|
||||
(int) (AllConfigs.SERVER.kinetics.inWorldProcessingTime.get() * timeModifierForStackSize) + 1;
|
||||
transported.processingTime = processingTime;
|
||||
if (!canProcess(transported.stack, type, world))
|
||||
if (!type.canProcess(transported.stack, world))
|
||||
transported.processingTime = -1;
|
||||
return ignore;
|
||||
}
|
||||
|
@ -201,29 +160,29 @@ public class InWorldProcessing {
|
|||
return null;
|
||||
}
|
||||
if (type == Type.HAUNTING) {
|
||||
SOUL_SMOKING_WRAPPER.setItem(0, stack);
|
||||
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(SOUL_SMOKING_WRAPPER, world);
|
||||
HAUNTING_WRAPPER.setItem(0, stack);
|
||||
Optional<HauntingRecipe> recipe = AllRecipeTypes.HAUNTING.find(HAUNTING_WRAPPER, world);
|
||||
if (recipe.isPresent())
|
||||
return applyRecipeOn(stack, recipe.get());
|
||||
return null;
|
||||
}
|
||||
|
||||
WRAPPER.setItem(0, stack);
|
||||
RECIPE_WRAPPER.setItem(0, stack);
|
||||
Optional<SmokingRecipe> smokingRecipe = world.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.SMOKING, WRAPPER, world);
|
||||
.getRecipeFor(RecipeType.SMOKING, RECIPE_WRAPPER, world);
|
||||
|
||||
if (type == Type.BLASTING) {
|
||||
if (!smokingRecipe.isPresent()) {
|
||||
WRAPPER.setItem(0, stack);
|
||||
RECIPE_WRAPPER.setItem(0, stack);
|
||||
Optional<SmeltingRecipe> smeltingRecipe = world.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.SMELTING, WRAPPER, world);
|
||||
.getRecipeFor(RecipeType.SMELTING, RECIPE_WRAPPER, world);
|
||||
|
||||
if (smeltingRecipe.isPresent())
|
||||
return applyRecipeOn(stack, smeltingRecipe.get());
|
||||
|
||||
WRAPPER.setItem(0, stack);
|
||||
RECIPE_WRAPPER.setItem(0, stack);
|
||||
Optional<BlastingRecipe> blastingRecipe = world.getRecipeManager()
|
||||
.getRecipeFor(RecipeType.BLASTING, WRAPPER, world);
|
||||
.getRecipeFor(RecipeType.BLASTING, RECIPE_WRAPPER, world);
|
||||
|
||||
if (blastingRecipe.isPresent())
|
||||
return applyRecipeOn(stack, blastingRecipe.get());
|
||||
|
@ -313,37 +272,220 @@ public class InWorldProcessing {
|
|||
return stacks;
|
||||
}
|
||||
|
||||
public static void spawnParticlesForProcessing(@Nullable Level world, Vec3 vec, Type type) {
|
||||
if (world == null || !world.isClientSide)
|
||||
return;
|
||||
if (world.random.nextInt(8) != 0)
|
||||
return;
|
||||
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);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case BLASTING:
|
||||
world.addParticle(ParticleTypes.LARGE_SMOKE, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
|
||||
break;
|
||||
case SMOKING:
|
||||
world.addParticle(ParticleTypes.POOF, vec.x, vec.y + .25f, vec.z, 0, 1 / 16f, 0);
|
||||
break;
|
||||
case HAUNTING:
|
||||
vec = vec.add(VecHelper.offsetRandomly(Vec3.ZERO, world.random, 1)
|
||||
.multiply(1, 0.05f, 1)
|
||||
.normalize()
|
||||
.scale(0.15f));
|
||||
world.addParticle(ParticleTypes.SOUL_FIRE_FLAME, vec.x, vec.y + .45f, vec.z, 0, 0, 0);
|
||||
if (world.random.nextInt(2) == 0)
|
||||
world.addParticle(ParticleTypes.SMOKE, vec.x, vec.y + .25f, vec.z, 0, 0, 0);
|
||||
break;
|
||||
case SPLASHING:
|
||||
Vector3f color = new Color(0x0055FF).asVectorF();
|
||||
world.addParticle(new DustParticleOptions(color, 1), vec.x + (world.random.nextFloat() - .5f) * .5f,
|
||||
vec.y + .5f, vec.z + (world.random.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
||||
world.addParticle(ParticleTypes.SPIT, vec.x + (world.random.nextFloat() - .5f) * .5f, vec.y + .5f,
|
||||
vec.z + (world.random.nextFloat() - .5f) * .5f, 0, 1 / 8f, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@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(DamageSource.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(FIRE_DAMAGE_SOURCE, 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(LAVA_DAMAGE_SOURCE, 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
|
||||
|| BlockTags.CAMPFIRES.contains(block) && 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Random;
|
|||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.wrench.IWrenchable;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
|
@ -17,6 +18,7 @@ import net.minecraft.world.InteractionHand;
|
|||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.ShovelItem;
|
||||
import net.minecraft.world.level.BlockGetter;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
|
@ -30,9 +32,12 @@ import net.minecraft.world.phys.shapes.CollisionContext;
|
|||
import net.minecraft.world.phys.shapes.VoxelShape;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.common.ToolAction;
|
||||
|
||||
public class LitBlazeBurnerBlock extends Block implements IWrenchable {
|
||||
|
||||
public static final ToolAction EXTINGUISH_FLAME_ACTION = ToolAction.get(Create.asResource("extinguish_flame").toString());
|
||||
|
||||
public static final EnumProperty<FlameType> FLAME_TYPE = EnumProperty.create("flame_type", FlameType.class);
|
||||
|
||||
public LitBlazeBurnerBlock(Properties properties) {
|
||||
|
@ -51,6 +56,15 @@ public class LitBlazeBurnerBlock extends Block implements IWrenchable {
|
|||
BlockHitResult blockRayTraceResult) {
|
||||
ItemStack heldItem = player.getItemInHand(hand);
|
||||
|
||||
if (heldItem.getItem() instanceof ShovelItem || heldItem.getItem().canPerformAction(heldItem, EXTINGUISH_FLAME_ACTION)) {
|
||||
world.playSound(player, pos, SoundEvents.GENERIC_EXTINGUISH_FIRE, SoundSource.BLOCKS, 0.5f, 2);
|
||||
if (world.isClientSide)
|
||||
return InteractionResult.SUCCESS;
|
||||
heldItem.hurtAndBreak(1, player, p -> p.broadcastBreakEvent(hand));
|
||||
world.setBlockAndUpdate(pos, AllBlocks.BLAZE_BURNER.getDefaultState());
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
if (state.getValue(FLAME_TYPE) == FlameType.REGULAR) {
|
||||
if (heldItem.is(ItemTags.SOUL_FIRE_BASE_BLOCKS)) {
|
||||
world.playSound(player, pos, SoundEvents.SOUL_SAND_PLACE, SoundSource.BLOCKS, 1.0f, world.random.nextFloat() * 0.4F + 0.8F);
|
||||
|
|
|
@ -139,6 +139,7 @@ public interface ItemAttribute {
|
|||
EQUIPABLE(s -> s.getEquipmentSlot() != null),
|
||||
FURNACE_FUEL(AbstractFurnaceBlockEntity::isFuel),
|
||||
WASHABLE(InWorldProcessing::isWashable),
|
||||
HAUNTABLE(InWorldProcessing::isHauntable),
|
||||
CRUSHABLE((s, w) -> testRecipe(s, w, AllRecipeTypes.CRUSHING.getType())
|
||||
|| testRecipe(s, w, AllRecipeTypes.MILLING.getType())),
|
||||
SMELTABLE((s, w) -> testRecipe(s, w, RecipeType.SMELTING)),
|
||||
|
|
|
@ -392,6 +392,8 @@
|
|||
"create.item_attributes.furnace_fuel.inverted": "is not furnace fuel",
|
||||
"create.item_attributes.washable": "can be Washed",
|
||||
"create.item_attributes.washable.inverted": "cannot be Washed",
|
||||
"create.item_attributes.hauntable": "can be Haunted",
|
||||
"create.item_attributes.hauntable.inverted": "cannot be Haunted",
|
||||
"create.item_attributes.crushable": "can be Crushed",
|
||||
"create.item_attributes.crushable.inverted": "cannot be Crushed",
|
||||
"create.item_attributes.smeltable": "can be Smelted",
|
||||
|
|
Loading…
Reference in a new issue