this update was quite damaging

- DamageSource refactors
This commit is contained in:
TropheusJ 2023-06-29 05:05:25 -04:00
parent 4a9b8eda06
commit b1ecdf4fb6
25 changed files with 409 additions and 81 deletions

View File

@ -0,0 +1,51 @@
package com.simibubi.create;
import com.simibubi.create.foundation.damageTypes.DamageTypeData;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.tags.DamageTypeTags;
import net.minecraft.world.damagesource.DamageScaling;
import net.minecraft.world.damagesource.DamageType;
public class AllDamageTypes {
public static final DamageTypeData CUCKOO_SURPRISE = DamageTypeData.builder()
.simpleId("cuckoo_surprise")
.exhaustion(0.1f)
.scaling(DamageScaling.ALWAYS)
.tag(DamageTypeTags.IS_EXPLOSION)
.build();
public static final DamageTypeData CRUSH = DamageTypeData.builder()
.simpleId("crush")
.scaling(DamageScaling.ALWAYS)
.tag(DamageTypeTags.BYPASSES_ARMOR)
.build();
public static final DamageTypeData DRILL = DamageTypeData.builder()
.simpleId("mechanical_drill")
.tag(DamageTypeTags.BYPASSES_ARMOR)
.build();
public static final DamageTypeData FAN_FIRE = DamageTypeData.builder()
.simpleId("fan_fire")
.tag(DamageTypeTags.IS_FIRE, DamageTypeTags.BYPASSES_ARMOR)
.build();
public static final DamageTypeData FAN_LAVA = DamageTypeData.builder()
.simpleId("fan_lava")
.tag(DamageTypeTags.IS_FIRE, DamageTypeTags.BYPASSES_ARMOR)
.build();
public static final DamageTypeData SAW = DamageTypeData.builder()
.simpleId("mechanical_saw")
.tag(DamageTypeTags.BYPASSES_ARMOR)
.build();
public static final DamageTypeData ROLLER = DamageTypeData.builder()
.simpleId("mechanical_roller")
.build();
public static final DamageTypeData POTATO_CANNON = DamageTypeData.builder()
.simpleId("potato_cannon")
.build();
public static final DamageTypeData RUN_OVER = DamageTypeData.builder()
.simpleId("run_over")
.build();
public static void bootstrap(BootstapContext<DamageType> ctx) {
DamageTypeData.allInNamespace(Create.ID).forEach(data -> data.register(ctx));
}
}

View File

@ -2,6 +2,10 @@ package com.simibubi.create;
import java.util.Random;
import com.simibubi.create.foundation.damageTypes.DamageTypeDataProvider;
import com.simibubi.create.foundation.damageTypes.DamageTypeTagGen;
import org.slf4j.Logger;
import com.google.gson.Gson;
@ -183,6 +187,8 @@ public class Create {
gen.addProvider(true, new SequencedAssemblyRecipeGen(output));
ProcessingRecipeGen.registerAll(gen, output);
gen.addProvider(true, WorldgenDataProvider.makeFactory(event.getLookupProvider()));
gen.addProvider(true, DamageTypeDataProvider.makeFactory(event.getLookupProvider()));
gen.addProvider(true, new DamageTypeTagGen(output, event.getLookupProvider()));
}
}

View File

@ -9,6 +9,8 @@ import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import com.simibubi.create.AllDamageTypes;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableFloat;
import org.apache.commons.lang3.mutable.MutableObject;
@ -50,7 +52,7 @@ import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.MobCategory;
import net.minecraft.world.entity.item.ItemEntity;
@ -529,7 +531,7 @@ public class ContraptionCollider {
if (diffMotion.length() <= 0.35f || contraptionMotion.length() <= 0.35f)
return entityMotion;
EntityDamageSource pSource = new EntityDamageSource("create.run_over", contraptionEntity);
DamageSource source = AllDamageTypes.RUN_OVER.source(world, contraptionEntity);
double damage = diffMotion.length();
if (entity.getClassification(false) == MobCategory.MONSTER)
damage *= 2;
@ -543,7 +545,7 @@ public class ContraptionCollider {
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
SoundSource.NEUTRAL, 1, .75f);
} else {
entity.hurt(pSource, (int) (damage * 16));
entity.hurt(source, (int) (damage * 16));
world.playSound(null, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT, SoundSource.NEUTRAL, 1, .75f);
if (!entity.isAlive())
contraptionEntity.getControllingPlayer()

View File

@ -1,5 +1,6 @@
package com.simibubi.create.content.contraptions;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.content.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.foundation.networking.SimplePacketBase;
@ -7,7 +8,6 @@ import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent.Context;
@ -43,7 +43,7 @@ public class TrainCollisionPacket extends SimplePacketBase {
if (!(entity instanceof CarriageContraptionEntity cce))
return;
player.hurt(new EntityDamageSource("create.run_over", cce), (int) damage);
player.hurt(AllDamageTypes.RUN_OVER.source(level, cce), damage);
player.level().playSound(player, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT, SoundSource.NEUTRAL,
1, .75f);
});

View File

@ -91,7 +91,7 @@ public class PloughMovementBehaviour extends BlockBreakingMovementBehaviour {
}
@Override
protected boolean throwsEntities() {
protected boolean throwsEntities(Level level) {
return true;
}

View File

@ -31,9 +31,6 @@ import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;
public class RollerBlock extends AttachedActorBlock implements IBE<RollerBlockEntity> {
public static DamageSource damageSourceRoller = new DamageSource("create.mechanical_roller");
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
public RollerBlock(Properties p_i48377_1_) {

View File

@ -12,6 +12,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.content.contraptions.actors.roller.RollerBlockEntity.RollingMode;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.pulley.PulleyContraption;
@ -106,8 +107,8 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
}
@Override
protected DamageSource getDamageSource() {
return RollerBlock.damageSourceRoller;
protected DamageSource getDamageSource(Level level) {
return AllDamageTypes.ROLLER.source(level);
}
@Override
@ -135,7 +136,7 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
max = hardness;
argMax = toBreak;
}
if (argMax == null) {
triggerPaver(context, pos);
return;
@ -194,7 +195,7 @@ public class RollerMovementBehaviour extends BlockBreakingMovementBehaviour {
.isEmpty())
startingY = 0;
}
// Train
PaveTask profileForTracks = createHeightProfileForTracks(context);
if (profileForTracks != null) {

View File

@ -95,7 +95,7 @@ public class StickerBlock extends WrenchableDirectionalBlock implements IBE<Stic
public void fallOn(Level p_152426_, BlockState p_152427_, BlockPos p_152428_, Entity p_152429_, float p_152430_) {
if (!isUprightSticker(p_152426_, p_152428_) || p_152429_.isSuppressingBounce())
super.fallOn(p_152426_, p_152427_, p_152428_, p_152429_, p_152430_);
p_152429_.causeFallDamage(p_152430_, 1.0F, DamageSource.FALL);
p_152429_.causeFallDamage(p_152430_, 1.0F, p_152426_.damageSources().fall());
}
@Override

View File

@ -46,7 +46,7 @@ public class ClientMotionPacket extends SimplePacketBase {
sender.setDeltaMovement(motion);
sender.setOnGround(onGround);
if (onGround) {
sender.causeFallDamage(sender.fallDistance, 1, DamageSource.FALL);
sender.causeFallDamage(sender.fallDistance, 1, sender.damageSources().fall());
sender.fallDistance = 0;
sender.connection.aboveGroundTickCount = 0;
sender.connection.aboveGroundVehicleTickCount = 0;

View File

@ -1,7 +1,6 @@
package com.simibubi.create.content.equipment.potatoCannon;
import javax.annotation.Nullable;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.AllEnchantments;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.foundation.advancement.AllAdvancements;
@ -18,8 +17,8 @@ import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.DamageTypeTags;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.IndirectEntityDamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
@ -38,6 +37,8 @@ import net.minecraftforge.entity.IEntityAdditionalSpawnData;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
public class PotatoProjectileEntity extends AbstractHurtingProjectile implements IEntityAdditionalSpawnData {
protected PotatoCannonProjectileType type;
@ -293,8 +294,8 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
}
@Override
public boolean hurt(DamageSource source, float amt) {
if (source == DamageSource.IN_FIRE || source == DamageSource.ON_FIRE)
public boolean hurt(@NotNull DamageSource source, float amt) {
if (source.is(DamageTypeTags.IS_FIRE))
return false;
if (this.isInvulnerableTo(source))
return false;
@ -316,15 +317,7 @@ public class PotatoProjectileEntity extends AbstractHurtingProjectile implements
}
private DamageSource causePotatoDamage() {
return new PotatoDamageSource(this, getOwner()).setProjectile();
}
public static class PotatoDamageSource extends IndirectEntityDamageSource {
public PotatoDamageSource(Entity source, @Nullable Entity trueSource) {
super("create.potato_cannon", source, trueSource);
}
return AllDamageTypes.POTATO_CANNON.source(level(), getOwner(), this);
}
@SuppressWarnings("unchecked")

View File

@ -88,7 +88,7 @@ public class WrenchItem extends Item {
if (player.isCreative())
return;
AbstractMinecart minecart = (AbstractMinecart) target;
minecart.hurt(DamageSource.playerAttack(player), 100);
minecart.hurt(minecart.damageSources().playerAttack(player), 100);
}
@Override

View File

@ -42,7 +42,7 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
damageEntities(context, pos, world);
if (world.isClientSide)
return;
if (!canBreak(world, pos, stateVisited))
return;
context.data.put("BreakingPos", NbtUtils.writeBlockPos(pos));
@ -52,8 +52,8 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
public void damageEntities(MovementContext context, BlockPos pos, Level world) {
if (context.contraption.entity instanceof OrientedContraptionEntity oce && oce.nonDamageTicks > 0)
return;
DamageSource damageSource = getDamageSource();
if (damageSource == null && !throwsEntities())
DamageSource damageSource = getDamageSource(world);
if (damageSource == null && !throwsEntities(world))
return;
Entities: for (Entity entity : world.getEntitiesOfClass(Entity.class, new AABB(pos))) {
if (entity instanceof ItemEntity)
@ -72,7 +72,7 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
float damage = (float) Mth.clamp(6 * Math.pow(context.relativeMotion.length(), 0.4) + 1, 2, 10);
entity.hurt(damageSource, damage);
}
if (throwsEntities() && (world.isClientSide == (entity instanceof Player)))
if (throwsEntities(world) && (world.isClientSide == (entity instanceof Player)))
throwEntity(context, entity);
}
}
@ -89,12 +89,12 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
entity.hurtMarked = true;
}
protected DamageSource getDamageSource() {
protected DamageSource getDamageSource(Level level) {
return null;
}
protected boolean throwsEntities() {
return getDamageSource() != null;
protected boolean throwsEntities(Level level) {
return getDamageSource(level) != null;
}
@Override

View File

@ -2,6 +2,7 @@ package com.simibubi.create.content.kinetics.clock;
import java.util.List;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
@ -26,8 +27,6 @@ import net.minecraft.world.phys.Vec3;
public class CuckooClockBlockEntity extends KineticBlockEntity {
public static DamageSource CUCKOO_SURPRISE = new DamageSource("create.cuckoo_clock_explosion").setExplosion();
public LerpedFloat hourHand = LerpedFloat.angular();
public LerpedFloat minuteHand = LerpedFloat.angular();
public LerpedFloat animationProgress = LerpedFloat.linear();
@ -42,7 +41,7 @@ public class CuckooClockBlockEntity extends KineticBlockEntity {
super(type, pos, state);
animationType = Animation.NONE;
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
@ -105,7 +104,8 @@ public class CuckooClockBlockEntity extends KineticBlockEntity {
if (animationType == Animation.SURPRISE && Mth.equal(animationProgress.getValue(), 50)) {
Vec3 center = VecHelper.getCenterOf(worldPosition);
level.destroyBlock(worldPosition, false);
level.explode(null, CUCKOO_SURPRISE, null, center.x, center.y, center.z, 3, false,
DamageSource damageSource = AllDamageTypes.CUCKOO_SURPRISE.source(level);
level.explode(null, damageSource, null, center.x, center.y, center.z, 3, false,
ExplosionInteraction.BLOCK);
}

View File

@ -2,6 +2,7 @@ package com.simibubi.create.content.kinetics.crusher;
import java.util.List;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
@ -9,7 +10,6 @@ import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
@ -22,10 +22,6 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@EventBusSubscriber
public class CrushingWheelBlockEntity extends KineticBlockEntity {
public static final DamageSource DAMAGE_SOURCE = new DamageSource("create.crush").bypassArmor()
.setScalesWithDifficulty();
public CrushingWheelBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
setLazyTickRate(20);
@ -36,7 +32,7 @@ public class CrushingWheelBlockEntity extends KineticBlockEntity {
super.addBehaviours(behaviours);
registerAwardables(behaviours, AllAdvancements.CRUSHING_WHEEL, AllAdvancements.CRUSHER_MAXED);
}
@Override
public void onSpeedChanged(float prevSpeed) {
super.onSpeedChanged(prevSpeed);
@ -62,14 +58,14 @@ public class CrushingWheelBlockEntity extends KineticBlockEntity {
@SubscribeEvent
public static void crushingIsFortunate(LootingLevelEvent event) {
if (event.getDamageSource() != DAMAGE_SOURCE)
if (!AllDamageTypes.CRUSH.is(event.getDamageSource()))
return;
event.setLootingLevel(2); //This does not currently increase mob drops. It seems like this only works for damage done by an entity.
}
@SubscribeEvent
public static void handleCrushedMobDrops(LivingDropsEvent event) {
if (event.getSource() != CrushingWheelBlockEntity.DAMAGE_SOURCE)
if (!AllDamageTypes.CRUSH.is(event.getSource()))
return;
Vec3 outSpeed = Vec3.ZERO;
for (ItemEntity outputItem : event.getDrops()) {

View File

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Optional;
import java.util.UUID;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.AllRecipeTypes;
import com.simibubi.create.content.kinetics.belt.behaviour.DirectBeltInputBehaviour;
import com.simibubi.create.content.processing.recipe.ProcessingInventory;
@ -230,7 +231,7 @@ public class CrushingWheelControllerBlockEntity extends SmartBlockEntity {
processingEntity.setPos(entityOutPos.x, entityOutPos.y, entityOutPos.z);
}
}
processingEntity.hurt(CrushingWheelBlockEntity.DAMAGE_SOURCE, crusherDamage);
processingEntity.hurt(AllDamageTypes.CRUSH.source(level), crusherDamage);
if (!processingEntity.isAlive()) {
processingEntity.setPos(entityOutPos.x, entityOutPos.y, entityOutPos.z);
}

View File

@ -24,7 +24,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.damagesource.EntityDamageSource;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
@ -110,7 +110,7 @@ public class DeployerFakePlayer extends FakePlayer {
public UUID getUUID() {
return owner == null ? super.getUUID() : owner;
}
@SubscribeEvent
public static void deployerHasEyesOnHisFeet(EntityEvent.Size event) {
if (event.getEntity() instanceof DeployerFakePlayer)
@ -119,9 +119,7 @@ public class DeployerFakePlayer extends FakePlayer {
@SubscribeEvent(priority = EventPriority.LOWEST)
public static void deployerCollectsDropsFromKilledEntities(LivingDropsEvent event) {
if (!(event.getSource() instanceof EntityDamageSource))
return;
EntityDamageSource source = (EntityDamageSource) event.getSource();
DamageSource source = event.getSource();
Entity trueSource = source.getEntity();
if (trueSource != null && trueSource instanceof DeployerFakePlayer) {
DeployerFakePlayer fakePlayer = (DeployerFakePlayer) trueSource;

View File

@ -7,6 +7,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.kinetics.base.DirectionalKineticBlock;
import com.simibubi.create.foundation.block.IBE;
@ -50,10 +51,8 @@ import net.minecraft.world.phys.shapes.VoxelShape;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class DrillBlock extends DirectionalKineticBlock implements IBE<DrillBlockEntity>, SimpleWaterloggedBlock {
public static DamageSource damageSourceDrill = new DamageSource("create.mechanical_drill").bypassArmor();
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
public DrillBlock(Properties properties) {
super(properties);
registerDefaultState(super.defaultBlockState().setValue(BlockStateProperties.WATERLOGGED, false));
@ -69,7 +68,7 @@ public class DrillBlock extends DirectionalKineticBlock implements IBE<DrillBloc
withBlockEntityDo(worldIn, pos, be -> {
if (be.getSpeed() == 0)
return;
entityIn.hurt(damageSourceDrill, (float) getDamage(be.getSpeed()));
entityIn.hurt(AllDamageTypes.DRILL.source(worldIn), (float) getDamage(be.getSpeed()));
});
}
@ -168,7 +167,7 @@ public class DrillBlock extends DirectionalKineticBlock implements IBE<DrillBloc
@MethodsReturnNonnullByDefault
private static class PlacementHelper implements IPlacementHelper {
@Override
public Predicate<ItemStack> getItemPredicate() {
return AllBlocks.MECHANICAL_DRILL::isIn;

View File

@ -4,6 +4,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.AllTags;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ActorInstance;
@ -56,8 +57,8 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
}
@Override
protected DamageSource getDamageSource() {
return DrillBlock.damageSourceDrill;
protected DamageSource getDamageSource(Level level) {
return AllDamageTypes.DRILL.source(level);
}
@Override

View File

@ -7,6 +7,8 @@ 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;
@ -57,12 +59,6 @@ import net.minecraftforge.items.ItemStackHandler;
import net.minecraftforge.items.wrapper.RecipeWrapper;
public class FanProcessing {
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 HAUNTING_WRAPPER = new HauntingWrapper();
@ -270,7 +266,7 @@ public class FanProcessing {
if (!entity.fireImmune()) {
entity.setSecondsOnFire(2);
entity.hurt(FIRE_DAMAGE_SOURCE, 2);
entity.hurt(AllDamageTypes.FAN_FIRE.source(level), 2);
}
}
@ -368,7 +364,7 @@ public class FanProcessing {
if (!entity.fireImmune()) {
entity.setSecondsOnFire(10);
entity.hurt(LAVA_DAMAGE_SOURCE, 4);
entity.hurt(AllDamageTypes.FAN_LAVA.source(level), 4);
}
}

View File

@ -7,6 +7,7 @@ import javax.annotation.ParametersAreNonnullByDefault;
import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.AllShapes;
import com.simibubi.create.content.kinetics.base.DirectionalAxisKineticBlock;
import com.simibubi.create.content.kinetics.drill.DrillBlock;
@ -49,8 +50,6 @@ import net.minecraft.world.phys.shapes.VoxelShape;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
public class SawBlock extends DirectionalAxisKineticBlock implements IBE<SawBlockEntity> {
public static DamageSource damageSourceSaw = new DamageSource("create.mechanical_saw").bypassArmor();
public static final BooleanProperty FLIPPED = BooleanProperty.create("flipped");
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());
@ -163,7 +162,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IBE<SawBloc
withBlockEntityDo(worldIn, pos, be -> {
if (be.getSpeed() == 0)
return;
entityIn.hurt(damageSourceSaw, (float) DrillBlock.getDamage(be.getSpeed()));
entityIn.hurt(AllDamageTypes.SAW.source(worldIn), (float) DrillBlock.getDamage(be.getSpeed()));
});
}
@ -252,7 +251,7 @@ public class SawBlock extends DirectionalAxisKineticBlock implements IBE<SawBloc
.setValue(FLIPPED, state.getValue(FLIPPED)));
}
}
}
}

View File

@ -3,6 +3,7 @@ package com.simibubi.create.content.kinetics.saw;
import java.util.Optional;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.AllDamageTypes;
import com.simibubi.create.content.contraptions.behaviour.MovementContext;
import com.simibubi.create.content.contraptions.render.ContraptionMatrices;
import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour;
@ -102,7 +103,7 @@ public class SawMovementBehaviour extends BlockBreakingMovementBehaviour {
}
@Override
protected DamageSource getDamageSource() {
return SawBlock.damageSourceSaw;
protected DamageSource getDamageSource(Level level) {
return AllDamageTypes.SAW.source(level);
}
}

View File

@ -44,24 +44,24 @@ public class EjectorBlock extends HorizontalKineticBlock implements IBE<EjectorB
super(properties);
registerDefaultState(defaultBlockState().setValue(WATERLOGGED, false));
}
@Override
protected void createBlockStateDefinition(Builder<Block, BlockState> pBuilder) {
super.createBlockStateDefinition(pBuilder.add(WATERLOGGED));
}
@Override
public FluidState getFluidState(BlockState pState) {
return fluidState(pState);
}
@Override
public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState,
LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) {
updateWater(pLevel, pState, pCurrentPos);
return pState;
}
@Override
public BlockState getStateForPlacement(BlockPlaceContext pContext) {
return withWater(super.getStateForPlacement(pContext), pContext);
@ -91,7 +91,7 @@ public class EjectorBlock extends HorizontalKineticBlock implements IBE<EjectorB
float p_180658_4_) {
Optional<EjectorBlockEntity> blockEntityOptional = getBlockEntityOptional(p_180658_1_, p_180658_2_);
if (blockEntityOptional.isPresent() && !p_180658_3_.isSuppressingBounce()) {
p_180658_3_.causeFallDamage(p_180658_4_, 1.0F, DamageSource.FALL);
p_180658_3_.causeFallDamage(p_180658_4_, 1.0F, p_180658_1_.damageSources().fall());
return;
}
super.fallOn(p_180658_1_, p_152427_, p_180658_2_, p_180658_3_, p_180658_4_);

View File

@ -0,0 +1,209 @@
package com.simibubi.create.foundation.damageTypes;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import com.simibubi.create.Create;
import net.minecraft.core.Holder;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.worldgen.BootstapContext;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.CombatEntry;
import net.minecraft.world.damagesource.CombatTracker;
import net.minecraft.world.damagesource.DamageEffects;
import net.minecraft.world.damagesource.DamageScaling;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageSources;
import net.minecraft.world.damagesource.DamageType;
import net.minecraft.world.damagesource.DeathMessageType;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LevelReader;
/**
* An extension of {@link DamageType} that contains extra data, functionality, and utility.
* @see DamageType
* @see DamageSource
* @see DamageSources
*/
public class DamageTypeData {
private static final List<DamageTypeData> all = new ArrayList<>();
public final ResourceKey<DamageType> key;
public final ResourceLocation id;
public final DamageType type;
public final Collection<TagKey<DamageType>> tags;
private Holder<DamageType> holder;
private final Map<LevelReader, DamageSource> staticSourceCache = new WeakHashMap<>();
protected DamageTypeData(ResourceKey<DamageType> key, DamageType type, Collection<TagKey<DamageType>> tags) {
this.key = key;
this.id = key.location();
this.type = type;
this.tags = tags;
}
public DamageSource source(LevelReader level) {
if (!staticSourceCache.containsKey(level)) {
Holder<DamageType> holder = getHolder(level);
staticSourceCache.put(level, new DamageSource(holder));
}
return staticSourceCache.get(level);
}
public DamageSource source(LevelReader level, @Nullable Entity entity) {
return new DamageSource(getHolder(level), entity);
}
public DamageSource source(LevelReader level, @Nullable Entity cause, @Nullable Entity direct) {
return new DamageSource(getHolder(level), cause, direct);
}
private Holder<DamageType> getHolder(LevelReader level) {
if (this.holder == null) {
Registry<DamageType> registry = level.registryAccess().registryOrThrow(Registries.DAMAGE_TYPE);
this.holder = registry.getHolderOrThrow(key);
}
return holder;
}
public boolean is(@Nullable DamageSource source) {
return source != null && is(source.type());
}
public boolean is(DamageType type) {
return this.type.equals(type);
}
public void register(BootstapContext<DamageType> ctx) {
ctx.register(this.key, this.type);
}
public static Stream<DamageTypeData> allInNamespace(String namespace) {
return all.stream().filter(data -> data.id.getNamespace().equals(namespace));
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
// required
private String msgId;
private ResourceLocation location;
// defaulted
private float exhaustion = 0;
private DamageScaling scaling = DamageScaling.WHEN_CAUSED_BY_LIVING_NON_PLAYER;
private DamageEffects effects = DamageEffects.HURT;
private DeathMessageType deathMessageType = DeathMessageType.DEFAULT;
private final List<TagKey<DamageType>> tags = new ArrayList<>();
/**
* Set the ResourceLocation or ID of this type. This is a required field.
*/
public Builder location(ResourceLocation location) {
this.location = location;
return this;
}
public Builder location(String path) {
return location(Create.asResource(path));
}
/**
* Set both the location and msgId of this type from one ResourceLocation.
* The msgId is set to "namespace.path".
*/
public Builder simpleId(ResourceLocation location) {
location(location);
return msgId(location.getNamespace() + '.' + location.getPath());
}
public Builder simpleId(String path) {
return simpleId(Create.asResource(path));
}
/**
* Set the message ID. this is used for death message lang keys. This is a required field.
*
* @see #deathMessageType(DeathMessageType)
*/
public Builder msgId(String msgId) {
this.msgId = msgId;
return this;
}
/**
* Set the exhaustion of this type. This is the amount of hunger that will be consumed when an entity is damaged.
*/
public Builder exhaustion(float exhaustion) {
this.exhaustion = exhaustion;
return this;
}
/**
* Set the scaling of this type. This determines whether damage is increased based on difficulty or not.
*/
public Builder scaling(DamageScaling scaling) {
this.scaling = scaling;
return this;
}
/**
* Set the effects of this type. This determines the sound that plays when damaged.
*/
public Builder effects(DamageEffects effects) {
this.effects = effects;
return this;
}
/**
* Set the death message type of this damage type. This determines how a death message lang key is assembled.
* <ul>
* <li>{@link DeathMessageType#DEFAULT}: {@link DamageSource#getLocalizedDeathMessage}</li>
* <li>{@link DeathMessageType#FALL_VARIANTS}: {@link CombatTracker#getFallMessage(CombatEntry, Entity)}</li>
* <li>{@link DeathMessageType#INTENTIONAL_GAME_DESIGN}: "death.attack." + msgId, wrapped in brackets, linking to MCPE-28723</li>
* </ul>
*/
@SuppressWarnings("JavadocReference")
public Builder deathMessageType(DeathMessageType type) {
this.deathMessageType = type;
return this;
}
@SafeVarargs
public final Builder tag(TagKey<DamageType>... tags) {
Collections.addAll(this.tags, tags);
return this;
}
public DamageTypeData build() {
if (location == null) {
throw new IllegalArgumentException("location is required");
}
if (msgId == null) {
throw new IllegalArgumentException("msgId is required");
}
DamageTypeData data = new DamageTypeData(
ResourceKey.create(Registries.DAMAGE_TYPE, location),
new DamageType(msgId, scaling, exhaustion, effects, deathMessageType),
tags
);
all.add(data);
return data;
}
}
}

View File

@ -0,0 +1,37 @@
package com.simibubi.create.foundation.damageTypes;
import java.util.Set;
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 net.minecraft.core.HolderLookup.Provider;
import net.minecraft.core.RegistrySetBuilder;
import net.minecraft.core.registries.Registries;
import net.minecraft.data.DataProvider;
import net.minecraft.data.PackOutput;
public class DamageTypeDataProvider extends DatapackBuiltinEntriesProvider {
private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder()
.add(Registries.DAMAGE_TYPE, AllDamageTypes::bootstrap);
public DamageTypeDataProvider(PackOutput output, CompletableFuture<Provider> registries) {
super(output, registries, BUILDER, Set.of(Create.ID));
}
public static DataProvider.Factory<DamageTypeDataProvider> makeFactory(CompletableFuture<Provider> registries) {
return output -> new DamageTypeDataProvider(output, registries);
}
@Override
@NotNull
public String getName() {
return "Create's Damage Type Data";
}
}

View File

@ -0,0 +1,41 @@
package com.simibubi.create.foundation.damageTypes;
import java.util.concurrent.CompletableFuture;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import com.simibubi.create.Create;
import org.jetbrains.annotations.NotNull;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.HolderLookup.Provider;
import net.minecraft.data.PackOutput;
import net.minecraft.data.tags.DamageTypeTagsProvider;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.TagKey;
import net.minecraft.world.damagesource.DamageType;
public class DamageTypeTagGen extends DamageTypeTagsProvider {
private final String namespace;
public DamageTypeTagGen(String namespace, PackOutput pOutput, CompletableFuture<HolderLookup.Provider> pLookupProvider) {
super(pOutput, pLookupProvider);
this.namespace = namespace;
}
public DamageTypeTagGen(PackOutput pOutput, CompletableFuture<HolderLookup.Provider> pLookupProvider) {
this(Create.ID, pOutput, pLookupProvider);
}
@Override
protected void addTags(@NotNull Provider provider) {
Multimap<TagKey<DamageType>, ResourceKey<DamageType>> tagsToTypes = HashMultimap.create();
DamageTypeData.allInNamespace(namespace).forEach(data -> data.tags.forEach(tag -> tagsToTypes.put(tag, data.key)));
tagsToTypes.asMap().forEach((tag, keys) -> {
TagAppender<DamageType> appender = tag(tag);
keys.forEach(appender::add);
});
}
}