From cd6bc52270776fcd1f54c8d74037cce0a9af1372 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Tue, 20 May 2025 08:35:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=81=E8=AE=B8=E4=BD=BF=E7=94=A8=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8C=85=E5=AE=9A=E4=B9=89DamageModifier=EF=BC=8C?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AE=9E=E4=BD=93=E7=B1=BB=E5=9E=8B=E4=BC=A4?= =?UTF-8?q?=E5=AE=B3=E5=85=8D=E7=96=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/vehicle/DefaultVehicleData.java | 11 ++- .../data/vehicle/VehicleData.java | 20 +++++ .../entity/vehicle/Tom6Entity.java | 7 -- .../entity/vehicle/base/VehicleEntity.java | 15 ++-- .../entity/vehicle/damage/DamageModifier.java | 67 +++++++++++++++ .../entity/vehicle/damage/DamageModify.java | 84 ++++++++++++++++--- .../data/superbwarfare/vehicles/tom_6.json | 9 +- 7 files changed, 182 insertions(+), 31 deletions(-) diff --git a/src/main/java/com/atsuishio/superbwarfare/data/vehicle/DefaultVehicleData.java b/src/main/java/com/atsuishio/superbwarfare/data/vehicle/DefaultVehicleData.java index 4e3969415..ac32751b9 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/vehicle/DefaultVehicleData.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/vehicle/DefaultVehicleData.java @@ -1,8 +1,11 @@ package com.atsuishio.superbwarfare.data.vehicle; import com.atsuishio.superbwarfare.config.server.VehicleConfig; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModify; import com.google.gson.annotations.SerializedName; +import java.util.List; + public class DefaultVehicleData { @SerializedName("ID") public String id = ""; @@ -25,7 +28,9 @@ public class DefaultVehicleData { @SerializedName("AllowFreeCam") public boolean allowFreeCam = false; - // TODO damage modifier -// @SerializedName("DamageModifier") -// private List damageModifier; + @SerializedName("ApplyDefaultDamageModifiers") + public boolean applyDefaultDamageModifiers = true; + + @SerializedName("DamageModifiers") + public List damageModifiers = List.of(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/data/vehicle/VehicleData.java b/src/main/java/com/atsuishio/superbwarfare/data/vehicle/VehicleData.java index 8a2e768a1..73fe49b91 100644 --- a/src/main/java/com/atsuishio/superbwarfare/data/vehicle/VehicleData.java +++ b/src/main/java/com/atsuishio/superbwarfare/data/vehicle/VehicleData.java @@ -1,9 +1,12 @@ package com.atsuishio.superbwarfare.data.vehicle; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; +import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; +import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; +import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -53,4 +56,21 @@ public class VehicleData { return data.allowFreeCam; } + public DamageModifier damageModifier() { + var modifier = new DamageModifier(); + + if (data.applyDefaultDamageModifiers) { + modifier.immuneTo(EntityType.POTION) + .immuneTo(EntityType.AREA_EFFECT_CLOUD) + .immuneTo(DamageTypes.FALL) + .immuneTo(DamageTypes.DROWN) + .immuneTo(DamageTypes.DRAGON_BREATH) + .immuneTo(DamageTypes.WITHER) + .immuneTo(DamageTypes.WITHER_SKULL) + .reduce(5, ModDamageTypes.VEHICLE_STRIKE); + } + + return modifier.addAll(data.damageModifiers); + } + } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java index d1f0bcf05..19ce848f8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Tom6Entity.java @@ -6,7 +6,6 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition; -import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModSounds; import com.atsuishio.superbwarfare.tools.CustomExplosion; @@ -93,12 +92,6 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity { return false; } - @Override - public DamageModifier getDamageModifier() { - return super.getDamageModifier() - .multiply(2, ModDamageTypes.VEHICLE_STRIKE); - } - @Override public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) { if (player.getMainHandItem().is(Items.MELON) && !entityData.get(MELON)) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java index c0fac124f..232461a33 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java @@ -42,10 +42,12 @@ import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; -import net.minecraft.world.entity.*; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.Pose; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.AbstractArrow; -import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.entity.vehicle.DismountHelper; import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.Items; @@ -450,14 +452,7 @@ public abstract class VehicleEntity extends Entity { * @return DamageModifier */ public DamageModifier getDamageModifier() { - return new DamageModifier() - .immuneTo(source -> source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud) - .immuneTo(DamageTypes.FALL) - .immuneTo(DamageTypes.DROWN) - .immuneTo(DamageTypes.DRAGON_BREATH) - .immuneTo(DamageTypes.WITHER) - .immuneTo(DamageTypes.WITHER_SKULL) - .reduce(5, ModDamageTypes.VEHICLE_STRIKE); + return data().damageModifier(); } public float getSourceAngle(DamageSource source, float multiply) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java index f92973c0b..7d866139f 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModifier.java @@ -4,6 +4,7 @@ import net.minecraft.resources.ResourceKey; import net.minecraft.tags.TagKey; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageType; +import net.minecraft.world.entity.EntityType; import java.util.ArrayList; import java.util.List; @@ -55,6 +56,23 @@ public class DamageModifier { return this; } + /** + * 免疫指定类型的伤害 + * @param entityId 伤害来源实体ID + */ + public DamageModifier immuneTo(String entityId) { + immuneList.add(new DamageModify(DamageModify.ModifyType.IMMUNITY, 0, entityId)); + return this; + } + + /** + * 免疫指定类型的伤害 + * @param type 伤害来源实体类型 + */ + public DamageModifier immuneTo(EntityType type) { + return immuneTo(EntityType.getKey(type).toString()); + } + /** * 固定减少所有伤害一定数值 * @@ -98,6 +116,25 @@ public class DamageModifier { return this; } + /** + * 固定减少指定类型的伤害一定数值 + * @param value 要减少的数值 + * @param entityId 伤害来源实体ID + */ + public DamageModifier reduce(float value, String entityId) { + reduceList.add(new DamageModify(DamageModify.ModifyType.REDUCE, value, entityId)); + return this; + } + + /** + * 固定减少指定类型的伤害一定数值 + * @param value 要减少的数值 + * @param type 伤害来源实体类型 + */ + public DamageModifier reduce(float value, EntityType type) { + return reduce(value, EntityType.getKey(type).toString()); + } + /** * 将所有类型的伤害值乘以指定数值 * @@ -141,6 +178,25 @@ public class DamageModifier { return this; } + /** + * 将指定类型的伤害值乘以指定数值 + * @param value 要乘以的数值 + * @param entityId 伤害来源实体ID + */ + public DamageModifier multiply(float value, String entityId) { + multiplyList.add(new DamageModify(DamageModify.ModifyType.MULTIPLY, value, entityId)); + return this; + } + + /** + * 将指定类型的伤害值乘以指定数值 + * @param value 要乘以的数值 + * @param type 伤害来源实体类型 + */ + public DamageModifier multiply(float value, EntityType type) { + return multiply(value, EntityType.getKey(type).toString()); + } + /** * 自定义伤害值计算 * @@ -151,6 +207,17 @@ public class DamageModifier { return this; } + public DamageModifier addAll(List list) { + for (var damageModify : list) { + switch (damageModify.getType()) { + case IMMUNITY -> immuneList.add(damageModify); + case REDUCE -> reduceList.add(damageModify); + case MULTIPLY -> multiplyList.add(damageModify); + } + } + return this; + } + private final List combinedList = new ArrayList<>(); /** diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java index b883c61cb..7ef3fbb98 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/damage/DamageModify.java @@ -1,10 +1,13 @@ package com.atsuishio.superbwarfare.entity.vehicle.damage; import com.google.gson.annotations.SerializedName; +import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; import net.minecraft.tags.TagKey; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageType; +import net.minecraft.world.entity.EntityType; import java.util.function.Function; @@ -19,20 +22,41 @@ public class DamageModify { } @SerializedName("Value") - private float value; + private float value = 0; @SerializedName("Type") - private ModifyType type; + private ModifyType type = ModifyType.IMMUNITY; + + public ModifyType getType() { + return type; + } @SerializedName("Source") - private String source; + private String source = "All"; + + private transient String entityId = ""; + + // 必须默认为null,否则无法处理JSON读取Source的情况 + private transient SourceType sourceType = null; + + private enum SourceType { + TAG_KEY, + RESOURCE_KEY, + FUNCTION, + ENTITY_ID, + ALL, + } private transient TagKey sourceTagKey = null; private transient ResourceKey sourceKey = null; private transient Function condition = null; + public DamageModify() { + } + public DamageModify(ModifyType type, float value) { this.type = type; this.value = value; + this.sourceType = SourceType.ALL; } @@ -40,18 +64,43 @@ public class DamageModify { this.type = type; this.value = value; this.sourceTagKey = sourceTagKey; + this.sourceType = SourceType.TAG_KEY; } public DamageModify(ModifyType type, float value, ResourceKey sourceKey) { this.type = type; this.value = value; this.sourceKey = sourceKey; + this.sourceType = SourceType.RESOURCE_KEY; } public DamageModify(ModifyType type, float value, Function condition) { this.type = type; this.value = value; this.condition = condition; + this.sourceType = SourceType.FUNCTION; + } + + public DamageModify(ModifyType type, float value, String entityId) { + this.type = type; + this.value = value; + this.entityId = entityId; + this.sourceType = SourceType.ENTITY_ID; + } + + private void generateSourceType() { + if (source.startsWith("#")) { + sourceType = SourceType.TAG_KEY; + this.sourceTagKey = TagKey.create(Registries.DAMAGE_TYPE, ResourceLocation.parse(source.substring(1))); + } else if (source.startsWith("@")) { + sourceType = SourceType.ENTITY_ID; + this.entityId = source.substring(1); + } else if (!source.equals("All")) { + sourceType = SourceType.RESOURCE_KEY; + this.sourceKey = ResourceKey.create(Registries.DAMAGE_TYPE, ResourceLocation.parse(source)); + } else { + sourceType = SourceType.ALL; + } } /** @@ -61,14 +110,29 @@ public class DamageModify { * @return 伤害来源是否符合条件 */ public boolean match(DamageSource source) { - if (condition != null) { - return condition.apply(source); - } else if (sourceTagKey != null) { - return source.is(sourceTagKey); - } else if (sourceKey != null) { - return source.is(sourceKey); + if (sourceType == null) { + generateSourceType(); } - return true; + + return switch (sourceType) { + case TAG_KEY -> source.is(sourceTagKey); + case RESOURCE_KEY -> source.is(sourceKey); + case FUNCTION -> condition.apply(source); + case ENTITY_ID -> { + var directEntity = source.getDirectEntity(); + var entity = source.getEntity(); + + // TODO 是否考虑优先处理Entity而不是DirectEntity? + if (directEntity != null) { + yield EntityType.getKey(directEntity.getType()).toString().equals(this.entityId); + } else if (entity != null) { + yield EntityType.getKey(entity.getType()).toString().equals(this.entityId); + } else { + yield false; + } + } + case ALL -> true; + }; } /** diff --git a/src/main/resources/data/superbwarfare/vehicles/tom_6.json b/src/main/resources/data/superbwarfare/vehicles/tom_6.json index 3eb4b5c5a..8effb0bf4 100644 --- a/src/main/resources/data/superbwarfare/vehicles/tom_6.json +++ b/src/main/resources/data/superbwarfare/vehicles/tom_6.json @@ -3,5 +3,12 @@ "MaxHealth": 40, "MaxEnergy": 100000, "UpStep": 0.5, - "allowFreeCam": true + "allowFreeCam": true, + "DamageModifiers": [ + { + "Type": "Multiply", + "Value": 2, + "Source": "superbwarfare:vehicle_strike" + } + ] } \ No newline at end of file