Skip to content

Commit

Permalink
hazards part 2 (#1341)
Browse files Browse the repository at this point in the history
* fix component item eating happening twice

* make antidotes take off % of hazard time instead of a flat amount of it

* clean up how hazard effects are tracked and saved

* make paracetamol fully an LV recipe

* make formaldehyde an inhalation poison

* make it possible to add new hazard types (for custom lang keys etc.)

* spotless, datagen
  • Loading branch information
screret committed Jun 1, 2024
1 parent 92c8cd7 commit 336a8a2
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 344 deletions.
7 changes: 4 additions & 3 deletions src/generated/resources/assets/gtceu/lang/en_ud.json
Original file line number Diff line number Diff line change
Expand Up @@ -2516,14 +2516,15 @@
"gtceu.gui.toggle_view.disabled": ")spınןℲ( ʍǝıΛ ǝןbbo⟘",
"gtceu.gui.toggle_view.enabled": ")sɯǝʇI( ʍǝıΛ ǝןbbo⟘",
"gtceu.hazard.antidote.description": "sןıɐʇǝp ʍoɥs oʇ ʇɟıɥS pןoHㄥ§ ǝʇopıʇuⱯɐ§",
"gtceu.hazard.antidote.description.time_removed": "ǝɯıʇ ,sʇuǝɯןıɐ ʇuǝɹɹnɔ ɟo %ss sǝʌoɯǝᴚ",
"gtceu.hazard.antidote.description.time_removed.all": "ןןɐ",
"gtceu.hazard.antidote.description.effect_removed": "sʇɔǝɟɟǝ ,sʇuǝɯןıɐ ʇuǝɹɹnɔ ɟo %s%% sǝʌoɯǝᴚ",
"gtceu.hazard.antidote.description.effect_removed.all": "sʇɔǝɟɟǝ ,sʇuǝɯןıɐ ʇuǝɹɹnɔ ɟo ןןɐ sǝʌoɯǝᴚ",
"gtceu.hazard.antidote.description_shift": ":sǝdʎʇ sǝɹnƆɐ§",
"gtceu.hazard.contact_poison": "uosıoԀ ʇɔɐʇuoƆϛ§",
"gtceu.hazard.corrosive": "ǝʌısoɹɹoƆ9§",
"gtceu.hazard.description": "sןıɐʇǝp ʍoɥs oʇ ʇɟıɥS pןoHㄥ§ S∩OᗡᴚⱯZⱯHɔ§ן§",
"gtceu.hazard.description_shift": ":S∩OᗡᴚⱯZⱯHɔ§ן§",
"gtceu.hazard.inhalation_poison": "pǝןɐɥuı uǝɥʍ snouosıoԀᄅ§",
"gtceu.hazard.none": "snoɹǝbuɐᗡ ʇoNᄅ§",
"gtceu.hazard.radioactive": "ǝʌıʇɔɐoıpɐᴚǝ§",
"gtceu.io.both": "ɥʇoᗺ",
"gtceu.io.export": "ʇɹodxƎ",
Expand Down Expand Up @@ -5549,4 +5550,4 @@
"tile.gtceu.reinforced_foam.name": "ɯɐoℲ pǝɔɹoɟuıǝᴚ",
"tile.gtceu.reinforced_stone.name": "ǝuoʇS pǝɔɹoɟuıǝᴚ",
"tile.gtceu.seal.name": "ʞɔoןᗺ pǝןɐǝS"
}
}
7 changes: 4 additions & 3 deletions src/generated/resources/assets/gtceu/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -2547,14 +2547,15 @@
"gtceu.gui.toggle_view.disabled": "Toggle View (Fluids)",
"gtceu.gui.toggle_view.enabled": "Toggle View (Items)",
"gtceu.hazard.antidote.description": "§aAntidote §7Hold Shift to show details",
"gtceu.hazard.antidote.description.time_removed": "Removes %ss of current ailments' time",
"gtceu.hazard.antidote.description.time_removed.all": "all",
"gtceu.hazard.antidote.description.effect_removed": "Removes %s%% of current ailments' effects",
"gtceu.hazard.antidote.description.effect_removed.all": "Removes all of current ailments' effects",
"gtceu.hazard.antidote.description_shift": "§aCures types:",
"gtceu.hazard.contact_poison": "§5Contact Poison",
"gtceu.hazard.corrosive": "§6Corrosive",
"gtceu.hazard.description": "§l§cHAZARDOUS §7Hold Shift to show details",
"gtceu.hazard.description_shift": "§l§cHAZARDOUS:",
"gtceu.hazard.inhalation_poison": "§2Poisonous when inhaled",
"gtceu.hazard.none": "§2Not Dangerous",
"gtceu.hazard.radioactive": "§eRadioactive",
"gtceu.implosion_compressor": "Implosion Compressor",
"gtceu.io.both": "Both",
Expand Down Expand Up @@ -5546,4 +5547,4 @@
"tile.gtceu.reinforced_foam.name": "Reinforced Foam",
"tile.gtceu.reinforced_stone.name": "Reinforced Stone",
"tile.gtceu.seal.name": "Sealed Block"
}
}
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
package com.gregtechceu.gtceu.api.capability;

import com.gregtechceu.gtceu.api.material.material.Material;

import com.gregtechceu.gtceu.api.material.material.properties.HazardProperty;
import com.gregtechceu.gtceu.api.material.material.stack.UnificationEntry;
import it.unimi.dsi.fastutil.objects.Object2IntMap;

import java.util.Map;
import java.util.Set;

public interface IHazardEffectTracker {

/**
* @return a map of the hazard types to their effects.
* @return a set of hazard effect to how long it's been applied for.
*/
Map<HazardProperty.HazardType, Set<HazardProperty.HazardEffect>> getTypesToEffects();
Set<Material> getExtraHazards();

/**
* @return a map of hazard effect to how long it's been applied for.
* @return a map of material to how long its effects been applied for.
*/
Object2IntMap<HazardProperty.HazardEffect> getCurrentHazardEffects();
Object2IntMap<Material> getCurrentHazards();

/**
* @return the maximum air supply for the entity this is attached to. -1 for default (300).
*/
// default maxAirSupply for players is 300.
int getMaxAirSupply();

void removeHazardItem(UnificationEntry entry);
void startTick();

void addHazardItem(UnificationEntry entry);
void tick(Material material);

void tick();
void endTick();
}
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public ItemStack finishUsingItem(ItemStack stack, Level level, LivingEntity livi
stack = interactionItem.finishUsingItem(stack, level, livingEntity);
}
}
return super.finishUsingItem(stack, level, livingEntity);
return stack;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
package com.gregtechceu.gtceu.api.material.material.properties;

import com.gregtechceu.gtceu.api.item.TagPrefixItem;
import com.gregtechceu.gtceu.api.item.armor.ArmorComponentItem;
import com.gregtechceu.gtceu.api.material.ChemicalHelper;
import com.gregtechceu.gtceu.api.material.material.Material;
import com.gregtechceu.gtceu.api.material.material.stack.UnificationEntry;
import com.gregtechceu.gtceu.api.tag.TagPrefix;
import com.gregtechceu.gtceu.api.item.forge.GTBucketItem;
import com.gregtechceu.gtceu.common.data.GTMobEffects;
import com.gregtechceu.gtceu.config.ConfigHolder;
import com.gregtechceu.gtceu.data.recipe.CustomTags;

import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.core.Holder;
import net.minecraft.util.StringRepresentable;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.attributes.Attribute;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.item.ArmorItem;
import net.minecraft.world.item.BucketItem;
import net.minecraft.world.item.ItemStack;

import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
Expand Down Expand Up @@ -65,40 +69,45 @@ public HazardProperty(HazardType hazardType, List<HazardProperty.HazardEffect> e
@Override
public void verifyProperty(MaterialProperties properties) {}

public enum HazardType {
public record HazardType(String name, ProtectionType protectionType, Set<TagPrefix> affectedTagPrefixes)
implements StringRepresentable {

INHALATION_POISON(ProtectionType.MASK, TagPrefix.dust, TagPrefix.dustSmall, TagPrefix.dustTiny,
TagPrefix.dustPure, TagPrefix.dustImpure),
CONTACT_POISON(ProtectionType.FULL),
RADIOACTIVE(ProtectionType.FULL),
CORROSIVE(ProtectionType.HANDS, TagPrefix.dust, TagPrefix.dustSmall, TagPrefix.dustTiny),
NONE(ProtectionType.FULL);
public static final Map<String, HazardType> ALL_HAZARDS = new HashMap<>();

public static final HazardType[] ALL = { INHALATION_POISON, CONTACT_POISON, RADIOACTIVE, CORROSIVE };
public static final HazardType INHALATION_POISON = new HazardType("inhalation_poison", ProtectionType.MASK,
TagPrefix.dust, TagPrefix.dustSmall, TagPrefix.dustTiny, TagPrefix.dustPure, TagPrefix.dustImpure);
public static final HazardType CONTACT_POISON = new HazardType("contacy_poison", ProtectionType.FULL);
public static final HazardType RADIOACTIVE = new HazardType("radioactive", ProtectionType.FULL);
public static final HazardType CORROSIVE = new HazardType("corrosive", ProtectionType.HANDS,
TagPrefix.dust, TagPrefix.dustSmall, TagPrefix.dustTiny);
public static final HazardType NONE = new HazardType("none", ProtectionType.NONE);

private final Set<TagPrefix> affectedTagPrefixes = new HashSet<>();
@Getter
private final ProtectionType protectionType;
public HazardType {
ALL_HAZARDS.put(name, this);
}

HazardType(ProtectionType protectionType, TagPrefix... tagPrefixes) {
this.protectionType = protectionType;
public HazardType(String name, ProtectionType protectionType, TagPrefix... tagPrefixes) {
this(name, protectionType, new HashSet<>());
affectedTagPrefixes.addAll(Arrays.asList(tagPrefixes));
if (tagPrefixes.length > 0)
affectedTagPrefixes.add(null); // add a null for fluid, because they don't have a prefix but still need
// to always be harmful.
}

public boolean isAffected(TagPrefix prefix) {
if (affectedTagPrefixes.isEmpty()) return true; // empty list means all prefixes are affected
return affectedTagPrefixes.contains(prefix);
}

@Override
public String getSerializedName() {
return this.name;
}
}

public enum ProtectionType {

MASK(ArmorItem.Type.HELMET),
HANDS(ArmorItem.Type.CHESTPLATE),
FULL(ArmorItem.Type.BOOTS, ArmorItem.Type.HELMET, ArmorItem.Type.CHESTPLATE, ArmorItem.Type.LEGGINGS);
FULL(ArmorItem.Type.BOOTS, ArmorItem.Type.HELMET, ArmorItem.Type.CHESTPLATE, ArmorItem.Type.LEGGINGS),
NONE();

@Getter
private final Set<ArmorItem.Type> equipmentTypes;
Expand All @@ -108,6 +117,9 @@ public enum ProtectionType {
}

public boolean isProtected(LivingEntity livingEntity) {
if (this == NONE) {
return true;
}
Set<ArmorItem.Type> correctArmorItems = new HashSet<>();
for (ArmorItem.Type equipmentType : equipmentTypes) {
ItemStack armor = livingEntity.getItemBySlot(equipmentType.getSlot());
Expand Down Expand Up @@ -149,7 +161,7 @@ public static HazardProperty.HazardEffect miningFautigueEffect(int duration, int

public static HazardProperty.HazardEffect poisonEffect(int duration, int startTime, int amplifier) {
return new HazardProperty.HazardEffect(duration, startTime,
() -> new MobEffectInstance(GTMobEffects.WEAK_POISON.get(), 1, amplifier));
() -> new MobEffectInstance(GTMobEffects.WEAK_POISON.getDelegate(), 1, amplifier));
}

public static HazardProperty.HazardEffect weaknessEffect(int duration, int startTime, int amplifier) {
Expand All @@ -162,6 +174,39 @@ public static HazardProperty.HazardEffect blindnessEffect(int duration, int star
() -> new MobEffectInstance(MobEffects.BLINDNESS, 1, amplifier));
}

@Nullable
public static Material getValidHazardMaterial(ItemStack item) {
Material material = null;
TagPrefix prefix = null;
boolean isFluid = false;
if (item.getItem() instanceof TagPrefixItem prefixItem) {
material = prefixItem.material;
prefix = prefixItem.tagPrefix;
} else if (item.getItem() instanceof BucketItem bucket) {
if (ConfigHolder.INSTANCE.gameplay.universalHazards || bucket instanceof GTBucketItem) {
material = ChemicalHelper.getMaterial(bucket.content);
isFluid = true;
}
} else if (ConfigHolder.INSTANCE.gameplay.universalHazards) {
UnificationEntry entry = ChemicalHelper.getUnificationEntry(item.getItem());
if (entry != null && entry.material != null) {
material = entry.material;
prefix = entry.tagPrefix;
}
}
if (material == null) {
return null;
}
HazardProperty property = material.getProperty(PropertyKey.HAZARD);
if (property == null) {
return null;
}
if (!isFluid && !property.getHazardType().isAffected(prefix)) {
return null;
}
return material;
}

/**
* @param damage amount of damage applied every {@code delay} seconds.
* @param delay damage is applied every {@code delay} seconds
Expand All @@ -178,7 +223,7 @@ public record HazardDamage(int damage, int delay) {}
* @param modifiers the attribute modifiers, if any.
*/
public record HazardEffect(int duration, int modifierStartTime, List<Supplier<MobEffectInstance>> effects,
Map<Attribute, AttributeModifier> modifiers, int newMaxAirSupply) {
Map<Holder<Attribute>, AttributeModifier> modifiers, int newMaxAirSupply) {

@SafeVarargs
public HazardEffect(int duration, Supplier<MobEffectInstance>... effects) {
Expand All @@ -190,15 +235,15 @@ public HazardEffect(int duration, int modifierStartTime, Supplier<MobEffectInsta
this(duration, modifierStartTime, Arrays.stream(effects).toList(), Object2ObjectMaps.emptyMap(), -1);
}

public HazardEffect(int secondsToMax, Map<Attribute, AttributeModifier> modifiers) {
public HazardEffect(int secondsToMax, Map<Holder<Attribute>, AttributeModifier> modifiers) {
this(secondsToMax, 0, List.of(), modifiers, -1);
}

public HazardEffect(int secondsToMax, int modifierStartTime, Map<Attribute, AttributeModifier> modifiers) {
public HazardEffect(int secondsToMax, int modifierStartTime, Map<Holder<Attribute>, AttributeModifier> modifiers) {
this(secondsToMax, modifierStartTime, List.of(), modifiers, -1);
}

public HazardEffect(int secondsToMax, Map<Attribute, AttributeModifier> modifiers, int maxAirModifier) {
public HazardEffect(int secondsToMax, Map<Holder<Attribute>, AttributeModifier> modifiers, int maxAirModifier) {
this(secondsToMax, 0, List.of(), modifiers, maxAirModifier);
}

Expand All @@ -225,11 +270,11 @@ public List<MobEffectInstance> getEffectInstancesAtTime(int timeFromStart) {
return effectInstances;
}

public Map<Attribute, AttributeModifier> getModifiersAtTime(int timeFromStart) {
public Map<Holder<Attribute>, AttributeModifier> getModifiersAtTime(int timeFromStart) {
if (this.modifiers.isEmpty()) {
return Object2ObjectMaps.emptyMap();
}
Map<Attribute, AttributeModifier> modifierMap = new HashMap<>();
Map<Holder<Attribute>, AttributeModifier> modifierMap = new HashMap<>();
for (var entry : this.modifiers.entrySet()) {
AttributeModifier modifier = entry.getValue();
double amount = modifier.amount() * (double) timeFromStart / Math.max(duration, 1);
Expand All @@ -245,48 +290,5 @@ public int getNewMaxAirSupplyAtTime(int timeFromStart) {
}
return newMaxAirSupply / Math.max(Math.round((float) timeFromStart / Math.max(duration, 1)), 1);
}

public CompoundTag serializeNBT() {
CompoundTag tag = new CompoundTag();
tag.putInt("duration", duration);
tag.putInt("modifier_start_time", modifierStartTime);

ListTag effectsTag = new ListTag();
for (Supplier<MobEffectInstance> effect : effects) {
effectsTag.add(effect.get().save());
}
tag.put("effects", effectsTag);
CompoundTag attributesTag = new CompoundTag();
for (Map.Entry<Attribute, AttributeModifier> modifier : modifiers.entrySet()) {
attributesTag.put(BuiltInRegistries.ATTRIBUTE.getKey(modifier.getKey()).toString(),
modifier.getValue().save());
}
tag.put("modifiers", attributesTag);
tag.putInt("max_air_supply", newMaxAirSupply);

return tag;
}

public static HazardEffect deserializeNBT(CompoundTag tag) {
int duration = tag.getInt("duration");
int modifierStartTime = tag.getInt("modifier_start_time");

List<Supplier<MobEffectInstance>> effects = new ArrayList<>();
for (Tag effect : tag.getList("effects", Tag.TAG_COMPOUND)) {
if (!(effect instanceof CompoundTag compoundTag)) {
continue;
}
effects.add(() -> MobEffectInstance.load(compoundTag));
}
Map<Attribute, AttributeModifier> modifiers = new HashMap<>();
CompoundTag attributesTag = tag.getCompound("modifiers");
for (String key : attributesTag.getAllKeys()) {
modifiers.put(BuiltInRegistries.ATTRIBUTE.get(new ResourceLocation(key)),
AttributeModifier.load(attributesTag.getCompound(key)));
}
int maxAirModifier = tag.getInt("max_air_supply");

return new HazardEffect(duration, modifierStartTime, effects, modifiers, maxAirModifier);
}
}
}
Loading

0 comments on commit 336a8a2

Please sign in to comment.