允许使用数据包定义DamageModifier,添加实体类型伤害免疫
This commit is contained in:
parent
e3d0a2959f
commit
cd6bc52270
7 changed files with 182 additions and 31 deletions
|
@ -1,8 +1,11 @@
|
||||||
package com.atsuishio.superbwarfare.data.vehicle;
|
package com.atsuishio.superbwarfare.data.vehicle;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||||
|
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModify;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class DefaultVehicleData {
|
public class DefaultVehicleData {
|
||||||
@SerializedName("ID")
|
@SerializedName("ID")
|
||||||
public String id = "";
|
public String id = "";
|
||||||
|
@ -25,7 +28,9 @@ public class DefaultVehicleData {
|
||||||
@SerializedName("AllowFreeCam")
|
@SerializedName("AllowFreeCam")
|
||||||
public boolean allowFreeCam = false;
|
public boolean allowFreeCam = false;
|
||||||
|
|
||||||
// TODO damage modifier
|
@SerializedName("ApplyDefaultDamageModifiers")
|
||||||
// @SerializedName("DamageModifier")
|
public boolean applyDefaultDamageModifiers = true;
|
||||||
// private List<DamageModify> damageModifier;
|
|
||||||
|
@SerializedName("DamageModifiers")
|
||||||
|
public List<DamageModify> damageModifiers = List.of();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
package com.atsuishio.superbwarfare.data.vehicle;
|
package com.atsuishio.superbwarfare.data.vehicle;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
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.CacheBuilder;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
|
import net.minecraft.world.damagesource.DamageTypes;
|
||||||
import net.minecraft.world.entity.EntityType;
|
import net.minecraft.world.entity.EntityType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -53,4 +56,21 @@ public class VehicleData {
|
||||||
return data.allowFreeCam;
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
|
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition;
|
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.ModDamageTypes;
|
||||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||||
|
@ -93,12 +92,6 @@ public class Tom6Entity extends MobileVehicleEntity implements GeoEntity {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public DamageModifier getDamageModifier() {
|
|
||||||
return super.getDamageModifier()
|
|
||||||
.multiply(2, ModDamageTypes.VEHICLE_STRIKE);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) {
|
public @NotNull InteractionResult interact(Player player, @NotNull InteractionHand hand) {
|
||||||
if (player.getMainHandItem().is(Items.MELON) && !entityData.get(MELON)) {
|
if (player.getMainHandItem().is(Items.MELON) && !entityData.get(MELON)) {
|
||||||
|
|
|
@ -42,10 +42,12 @@ import net.minecraft.world.InteractionHand;
|
||||||
import net.minecraft.world.InteractionResult;
|
import net.minecraft.world.InteractionResult;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.damagesource.DamageTypes;
|
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.player.Player;
|
||||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
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.entity.vehicle.DismountHelper;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.item.Items;
|
import net.minecraft.world.item.Items;
|
||||||
|
@ -450,14 +452,7 @@ public abstract class VehicleEntity extends Entity {
|
||||||
* @return DamageModifier
|
* @return DamageModifier
|
||||||
*/
|
*/
|
||||||
public DamageModifier getDamageModifier() {
|
public DamageModifier getDamageModifier() {
|
||||||
return new DamageModifier()
|
return data().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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getSourceAngle(DamageSource source, float multiply) {
|
public float getSourceAngle(DamageSource source, float multiply) {
|
||||||
|
|
|
@ -4,6 +4,7 @@ import net.minecraft.resources.ResourceKey;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.damagesource.DamageType;
|
import net.minecraft.world.damagesource.DamageType;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -55,6 +56,23 @@ public class DamageModifier {
|
||||||
return this;
|
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;
|
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;
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DamageModifier addAll(List<DamageModify> 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<DamageModify> combinedList = new ArrayList<>();
|
private final List<DamageModify> combinedList = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
package com.atsuishio.superbwarfare.entity.vehicle.damage;
|
package com.atsuishio.superbwarfare.entity.vehicle.damage;
|
||||||
|
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
import net.minecraft.core.registries.Registries;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.tags.TagKey;
|
import net.minecraft.tags.TagKey;
|
||||||
import net.minecraft.world.damagesource.DamageSource;
|
import net.minecraft.world.damagesource.DamageSource;
|
||||||
import net.minecraft.world.damagesource.DamageType;
|
import net.minecraft.world.damagesource.DamageType;
|
||||||
|
import net.minecraft.world.entity.EntityType;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@ -19,20 +22,41 @@ public class DamageModify {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SerializedName("Value")
|
@SerializedName("Value")
|
||||||
private float value;
|
private float value = 0;
|
||||||
@SerializedName("Type")
|
@SerializedName("Type")
|
||||||
private ModifyType type;
|
private ModifyType type = ModifyType.IMMUNITY;
|
||||||
|
|
||||||
|
public ModifyType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
@SerializedName("Source")
|
@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<DamageType> sourceTagKey = null;
|
private transient TagKey<DamageType> sourceTagKey = null;
|
||||||
private transient ResourceKey<DamageType> sourceKey = null;
|
private transient ResourceKey<DamageType> sourceKey = null;
|
||||||
private transient Function<DamageSource, Boolean> condition = null;
|
private transient Function<DamageSource, Boolean> condition = null;
|
||||||
|
|
||||||
|
public DamageModify() {
|
||||||
|
}
|
||||||
|
|
||||||
public DamageModify(ModifyType type, float value) {
|
public DamageModify(ModifyType type, float value) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
|
this.sourceType = SourceType.ALL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,18 +64,43 @@ public class DamageModify {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.sourceTagKey = sourceTagKey;
|
this.sourceTagKey = sourceTagKey;
|
||||||
|
this.sourceType = SourceType.TAG_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DamageModify(ModifyType type, float value, ResourceKey<DamageType> sourceKey) {
|
public DamageModify(ModifyType type, float value, ResourceKey<DamageType> sourceKey) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.sourceKey = sourceKey;
|
this.sourceKey = sourceKey;
|
||||||
|
this.sourceType = SourceType.RESOURCE_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DamageModify(ModifyType type, float value, Function<DamageSource, Boolean> condition) {
|
public DamageModify(ModifyType type, float value, Function<DamageSource, Boolean> condition) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.condition = condition;
|
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 伤害来源是否符合条件
|
* @return 伤害来源是否符合条件
|
||||||
*/
|
*/
|
||||||
public boolean match(DamageSource source) {
|
public boolean match(DamageSource source) {
|
||||||
if (condition != null) {
|
if (sourceType == null) {
|
||||||
return condition.apply(source);
|
generateSourceType();
|
||||||
} else if (sourceTagKey != null) {
|
|
||||||
return source.is(sourceTagKey);
|
|
||||||
} else if (sourceKey != null) {
|
|
||||||
return source.is(sourceKey);
|
|
||||||
}
|
}
|
||||||
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;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,5 +3,12 @@
|
||||||
"MaxHealth": 40,
|
"MaxHealth": 40,
|
||||||
"MaxEnergy": 100000,
|
"MaxEnergy": 100000,
|
||||||
"UpStep": 0.5,
|
"UpStep": 0.5,
|
||||||
"allowFreeCam": true
|
"allowFreeCam": true,
|
||||||
|
"DamageModifiers": [
|
||||||
|
{
|
||||||
|
"Type": "Multiply",
|
||||||
|
"Value": 2,
|
||||||
|
"Source": "superbwarfare:vehicle_strike"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue