Skip to content

Commit

Permalink
Add Status Effect and Potion Support (#4)
Browse files Browse the repository at this point in the history
* Status Effect and Potion Support

Adds support for virtual status effects and potion types. Currently no support for client screen/HUD element rendering (currently nothing renders in both cases)

* Fix TestMod status effect and add client display support

- Fixed the status effect in the test mod
- Added support for sending a vanilla status effect to the client (for display in the HUD/Inventory screen). This defaults to nothing being sent to the client
  • Loading branch information
aws404 authored Nov 13, 2021
1 parent 391409c commit f59dc10
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 7 deletions.
16 changes: 16 additions & 0 deletions src/main/java/eu/pb4/polymer/interfaces/VirtualStatusEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package eu.pb4.polymer.interfaces;

import net.minecraft.entity.effect.StatusEffect;

public interface VirtualStatusEffect extends VirtualObject {

/**
* Returns the effect to be displayed on the client's HUD.
* Note that particle color is determined by the server, so this will not affect them.
*
* @return Vanilla status effect, or <code>null</>null if nothing is to be displayed by the client
*/
default StatusEffect getVirtualStatusEffect() {
return null;
}
}
12 changes: 12 additions & 0 deletions src/main/java/eu/pb4/polymer/item/ItemHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
import net.minecraft.item.EnchantedBookItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.PotionItem;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString;
import net.minecraft.potion.PotionUtil;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.LiteralText;
import net.minecraft.text.MutableText;
Expand Down Expand Up @@ -80,6 +82,10 @@ public static ItemStack getVirtualItemStack(ItemStack itemStack, ServerPlayerEnt
return createBasicVirtualItemStack(itemStack, player);
}
}
} else if (itemStack.getItem() instanceof PotionItem) {
if (PotionUtil.getPotionEffects(itemStack).stream().anyMatch(statusEffectInstance -> statusEffectInstance.getEffectType() instanceof VirtualObject)) {
return createBasicVirtualItemStack(itemStack, player);
}
}

if (VIRTUAL_ITEM_CHECK.invoke(itemStack)) {
Expand Down Expand Up @@ -190,6 +196,12 @@ public static ItemStack createBasicVirtualItemStack(ItemStack itemStack, @Nullab
out.addEnchantment(Enchantments.VANISHING_CURSE, 0);
}

if (itemStack.getItem() instanceof PotionItem) {
if (!out.getOrCreateNbt().contains("CustomPotionColor")) {
out.getOrCreateNbt().putInt("CustomPotionColor", PotionUtil.getColor(itemStack));
}
}

NbtElement canDestroy = itemStack.getNbt().get("CanDestroy");

if (canDestroy != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package eu.pb4.polymer.mixin.other;

import eu.pb4.polymer.interfaces.VirtualStatusEffect;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.EntityStatusEffectS2CPacket;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(EntityStatusEffectS2CPacket.class)
public class EntityStatusEffectS2CPacketMixin {

@Mutable @Shadow @Final private byte effectId;

@Inject(method = "write", at = @At("HEAD"))
public void polymer_onWrite(PacketByteBuf buf, CallbackInfo callbackInfo) {
if (Registry.STATUS_EFFECT.get(this.effectId) instanceof VirtualStatusEffect virtualEffect && virtualEffect.getVirtualStatusEffect() != null) {
this.effectId = (byte) (StatusEffect.getRawId(virtualEffect.getVirtualStatusEffect()) & 255);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package eu.pb4.polymer.mixin.other;

import eu.pb4.polymer.interfaces.VirtualStatusEffect;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.RemoveEntityStatusEffectS2CPacket;
import net.minecraft.util.registry.Registry;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(RemoveEntityStatusEffectS2CPacket.class)
public class RemoveEntityStatusEffectS2CPacketMixin {

@Mutable @Shadow @Final private StatusEffect effectType;

@Inject(method = "write", at = @At("HEAD"))
public void polymer_onWrite(PacketByteBuf buf, CallbackInfo callbackInfo) {
if (effectType instanceof VirtualStatusEffect virtualEffect && virtualEffect.getVirtualStatusEffect() != null) {
this.effectType = ((VirtualStatusEffect) effectType).getVirtualStatusEffect();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@
import net.minecraft.network.PacketByteBuf;
import net.minecraft.network.packet.s2c.play.SynchronizeRecipesS2CPacket;
import net.minecraft.recipe.Recipe;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
Expand All @@ -24,8 +21,7 @@
public abstract class SynchronizeRecipesS2CPacketMixin {
@Unique List<Recipe<?>> rewrittenRecipes = null;

@Shadow @Mutable
private List<Recipe<?>> recipes;
@Final @Shadow @Mutable private List<Recipe<?>> recipes;

@Shadow public abstract void write(PacketByteBuf buf);

Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/polymer.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
"other.BootstrapMixin",
"other.CommandManagerMixin",
"other.DimensionTypeAccessor",
"other.EntityStatusEffectS2CPacketMixin",
"other.IdListMixin",
"other.RegistrySyncManagerMixin",
"other.RemoveEntityStatusEffectS2CPacketMixin",
"other.ServerPlayNetworkHandlerMixin",
"other.SynchronizeRecipesS2CPacketMixin",
"polymc.BlockPolyGeneratorMixin"
Expand Down
12 changes: 12 additions & 0 deletions src/testmod/java/eu/pb4/polymertest/TestMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
import net.minecraft.entity.attribute.EntityAttributeModifier;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectInstance;
import net.minecraft.item.*;
import net.minecraft.nbt.NbtElement;
import net.minecraft.network.packet.s2c.play.EntityAttributesS2CPacket;
import net.minecraft.network.packet.s2c.play.EntityTrackerUpdateS2CPacket;
import net.minecraft.potion.Potion;
import net.minecraft.text.LiteralText;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
Expand Down Expand Up @@ -66,6 +69,10 @@ public class TestMod implements ModInitializer {

public static Enchantment ENCHANTMENT;

public static final StatusEffect STATUS_EFFECT = new TestStatusEffect();
public static final Potion POTION = new Potion(new StatusEffectInstance(STATUS_EFFECT, 300));
public static final Potion LONG_POTION = new Potion("potion", new StatusEffectInstance(STATUS_EFFECT, 600));

public static final EntityType<TestEntity> ENTITY = FabricEntityTypeBuilder.<TestEntity>create(SpawnGroup.CREATURE, TestEntity::new).dimensions(EntityDimensions.fixed(0.75f, 1.8f)).build();
public static final EntityType<TestEntity2> ENTITY_2 = FabricEntityTypeBuilder.<TestEntity2>create(SpawnGroup.CREATURE, TestEntity2::new).dimensions(EntityDimensions.fixed(0.75f, 1.8f)).build();

Expand Down Expand Up @@ -107,8 +114,13 @@ public void onInitialize() {
Registry.register(Registry.BLOCK, new Identifier("test", "weak_glass"), WEAK_GLASS_BLOCK);
Registry.register(Registry.ITEM, new Identifier("test", "weak_glass"), WEAK_GLASS_BLOCK_ITEM);
Registry.register(Registry.ITEM, new Identifier("test", "ice_item"), ICE_ITEM);

ENCHANTMENT = Registry.register(Registry.ENCHANTMENT, new Identifier("test", "enchantment"), new TestEnchantment());

Registry.register(Registry.STATUS_EFFECT, new Identifier("test", "effect"), STATUS_EFFECT);
Registry.register(Registry.POTION, new Identifier("test", "potion"), POTION);
Registry.register(Registry.POTION, new Identifier("test", "long_potion"), LONG_POTION);

Registry.register(Registry.ENTITY_TYPE, new Identifier("test", "entity"), ENTITY);
FabricDefaultAttributeRegistry.register(ENTITY, TestEntity.createCreeperAttributes());

Expand Down
32 changes: 32 additions & 0 deletions src/testmod/java/eu/pb4/polymertest/TestStatusEffect.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package eu.pb4.polymertest;

import eu.pb4.polymer.interfaces.VirtualObject;
import eu.pb4.polymer.interfaces.VirtualStatusEffect;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.effect.StatusEffect;
import net.minecraft.entity.effect.StatusEffectCategory;
import net.minecraft.entity.effect.StatusEffects;

public class TestStatusEffect extends StatusEffect implements VirtualStatusEffect {
protected TestStatusEffect() {
super(StatusEffectCategory.BENEFICIAL, 110011);
}

@Override
public void applyUpdateEffect(LivingEntity entity, int amplifier) {
if (entity.getMainHandStack().isDamageable()) {
entity.getMainHandStack().damage(amplifier + 1, entity, entity1 -> entity1.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
}
}

@Override
public boolean canApplyUpdateEffect(int duration, int amplifier) {
return true;
}

@Override
public StatusEffect getVirtualStatusEffect() {
return StatusEffects.CONDUIT_POWER;
}
}
5 changes: 4 additions & 1 deletion src/testmod/resources/data/polymertest/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
{
"block.test.potato_block": "Tiny Potato",
"enchantment.test.enchantment": "TestEnch"
"enchantment.test.enchantment": "TestEnch",
"item.minecraft.potion.effect.potion": "TestPot",
"effect.test.effect": "Test Effect"

}

0 comments on commit f59dc10

Please sign in to comment.