今天我们在1.12.2的模组中尝试实现几种特殊的buff效果
1.在开发包中新建potion包 -> potion包中新建一个BaseSimplePotion类作为我们药水效果的基类:
BaseSimplePotion.java
package com.joy187.rejoymod.potion.buff;
import com.joy187.rejoymod.potion.ModPotions;
import com.joy187.rejoymod.util.Reference;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.init.PotionTypes;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
public class BaseSimplePotion extends Potion {
//确定所有效果贴图的位置
protected static final ResourceLocation resource = new ResourceLocation(Reference.Mod_ID,"textures/misc/potions.png");
protected final int iconIndex;
PotionType potionType=PotionTypes.MUNDANE;
// if (!this.world.isRemote)
// {
// layer.getPotion().applyAttributesModifiersToEntity(this, this.getAttributeMap(), layer.getAmplifier());
// }
public PotionType getPotionType() {
return potionType;
}
//参数:是否为debuff buff粒子颜色 buff名称 buff对应的图标
public BaseSimplePotion(boolean isBadEffectIn, int liquidColorIn, String name, int icon) {
super(isBadEffectIn, liquidColorIn);
setRegistryName(new ResourceLocation(Reference.Mod_ID, name));
setPotionName("rejoymod.potion." + name);
iconIndex = icon;
ModPotions.INSTANCES.add(this);
//setCreativeTab(tabs);
}
@SideOnly(Side.CLIENT)
protected void render(int x, int y, float alpha) {
Minecraft.getMinecraft().renderEngine.bindTexture(resource);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder buf = tessellator.getBuffer();
buf.begin(7, DefaultVertexFormats.POSITION_TEX);
GlStateManager.color(1, 1, 1, alpha);
int textureX = iconIndex % 14 * 18;
int textureY = 198 - iconIndex / 14 * 18;
buf.pos(x, y + 18, 0).tex(textureX * 0.00390625, (textureY + 18) * 0.00390625).endVertex();
buf.pos(x + 18, y + 18, 0).tex((textureX + 18) * 0.00390625, (textureY + 18) * 0.00390625).endVertex();
buf.pos(x + 18, y, 0).tex((textureX + 18) * 0.00390625, textureY * 0.00390625).endVertex();
buf.pos(x, y, 0).tex(textureX * 0.00390625, textureY * 0.00390625).endVertex();
tessellator.draw();
}
//在我们的个人界面显示药水效果UI
@Override
@SideOnly(Side.CLIENT)
public void renderInventoryEffect(int x, int y, PotionEffect effect, Minecraft mc) {
render(x + 6, y + 7, 1);
}
@Override
@SideOnly(Side.CLIENT)
public void renderHUDEffect(int x, int y, PotionEffect effect, Minecraft mc, float alpha) {
render(x + 3, y + 3, alpha);
}
}
2.在potion包中定义一个我们的效果类PotionZenHeart,让其继承我们的效果基类:
PotionZenHeart.java
package com.joy187.rejoymod.potion.buff;
import com.joy187.rejoymod.init.ModParticles;
import com.joy187.rejoymod.potion.ModPotions;
import com.joy187.rejoymod.util.EntityUtil;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.DamageSource;
import net.minecraft.world.World;
import net.minecraftforge.event.entity.living.LivingHurtEvent;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Random;
public class PotionZenHeart extends BasePotion {
public PotionZenHeart(boolean isBadEffectIn, int liquidColorIn, String name, int icon) {
super(isBadEffectIn, liquidColorIn, name, icon);
resistancePerLevel = 0.25f;
}
//我们药水的实际效果
@Override
public void performEffect(@Nonnull EntityLivingBase living, int amplified) {
Random ran = new Random();
int co = ran.nextInt(5);
//回血效果
if(co==4) living.heal(ran.nextFloat());
}
//当生物受伤,就减少其受到的魔法伤害
@SubscribeEvent
public static void onCreatureHurt(LivingHurtEvent event) {
World world = event.getEntity().getEntityWorld();
EntityLivingBase hurtOne = event.getEntityLiving();
if (event.isCanceled() || !event.getSource().isMagicDamage())
{
return;
}
//魔法减伤
Collection<PotionEffect> activePotionEffects = hurtOne.getActivePotionEffects();
for (int i = 0; i < activePotionEffects.size(); i++) {
PotionEffect buff = (PotionEffect)activePotionEffects.toArray()[i];
if (buff.getPotion() instanceof PotionZenHeart)
{
PotionZenHeart modBuff = (PotionZenHeart)buff.getPotion();
if (!world.isRemote)
{
float reduceRatio = modBuff.resistancePerLevel * (buff.getAmplifier());
event.setAmount(Math.max(1 - reduceRatio, 0f) * event.getAmount());
}
}
}
}
}
3.在potion包中新建一个ModPotions类,用于将我们所有的药水效果进行注册:
ModPotions.java
package com.joy187.rejoymod.potion;
import com.joy187.rejoymod.IdlFramework;
import com.joy187.rejoymod.init.InitPotionTypes;
import com.joy187.rejoymod.potion.buff.*;
import com.joy187.rejoymod.util.Reference;
import net.minecraft.init.MobEffects;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionType;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
@Mod.EventBusSubscriber(modid = Reference.Mod_ID)
public class ModPotions {
public static final List<Potion> INSTANCES = new ArrayList<Potion>();
public static final List<PotionType> TYPE_INSTANCES = new ArrayList<>();
//将模组中所有的药水效果都进行注册
//public static final PotionDeadly DEADLY = new PotionDeadly(true, 0x333333, "deadly", 0);
public static final PotionZenHeart ZEN_HEART = new PotionZenHeart(false, 0xcccc00, "zen_heart", 1);
//public static final PotionInsidiousDisease BURN = new PotionInsidiousDisease(true, 0x000033, "burn", 2);
//public static final PotionErosion EROSION = new PotionErosion(true, 0x660033, "erosion", 8);
@Nullable
private static Potion getRegisteredMobEffect(String id)
{
Potion potion = Potion.REGISTRY.getObject(new ResourceLocation(id));
if (potion == null)
{
throw new IllegalStateException("Invalid MobEffect requested: " + id);
}
else
{
return potion;
}
}
@SubscribeEvent
public static void registerPotions(RegistryEvent.Register<Potion> event)
{
// VIRUS_ONE.tuples.add(new EffectTuple(0.2f, MobEffects.NAUSEA, 100));
event.getRegistry().registerAll(INSTANCES.toArray(new Potion[0]));
IdlFramework.LogWarning("registered %d potion", INSTANCES.size());
}
@SubscribeEvent
public static void registerPotionTypes(RegistryEvent.Register<PotionType> evt) {
InitPotionTypes.init();
evt.getRegistry().registerAll(TYPE_INSTANCES.toArray(new PotionType[0]));
IdlFramework.Log("registered %d potion item(s)", TYPE_INSTANCES.size());
}
}
4.在potion包中新建ModPotionType类,用于说明我们的药水类型:
ModPotionType.java
package com.joy187.rejoymod.potion;
import com.joy187.rejoymod.util.Reference;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionType;
import javax.annotation.Nullable;
public class ModPotionType extends PotionType {
protected ModPotionType(PotionEffect... p_i46739_1_) {
this(null, p_i46739_1_);
}
public ModPotionType(@Nullable String p_i46740_1_, PotionEffect... p_i46740_2_) {
super(p_i46740_1_, p_i46740_2_);
setRegistryName(Reference.Mod_ID, p_i46740_1_);
ModPotions.TYPE_INSTANCES.add(this);
}
}
5.在init包中新建InitPotionTypes类,用于对我们的药水效果类型进行初始化工作:
InitPotionTypes.java
package com.joy187.rejoymod.init;
import com.joy187.rejoymod.item.ModItems;
import com.joy187.rejoymod.potion.ModPotionType;
import com.joy187.rejoymod.potion.ModPotions;
import net.minecraft.init.*;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.potion.PotionHelper;
import net.minecraft.potion.PotionType;
import static net.minecraft.init.PotionTypes.AWKWARD;
public class InitPotionTypes {
public static final PotionType BLINDNESS;
public static final PotionType LUCKY;
public static final PotionType UNLUCKY;
public static final PotionType HASTE;
public static final PotionType RESISTANCE;
public static final PotionType WITHER;
public static final PotionType LEVITATION;
public static final PotionType GLOWING;
//public static final PotionType LONG_BLINDNESS;
public static final int DURA_GOOD_3 = 1600;
public static final int DURA_GOOD_4 = 1200;
public static final ModPotionType REGEN_3 = new ModPotionType("regen_3", new PotionEffect(MobEffects.REGENERATION, 450, 2));
public static final ModPotionType REGEN_4 = new ModPotionType("regen_4", new PotionEffect(MobEffects.REGENERATION, 200, 3));
static
{
if (!Bootstrap.isRegistered())
{
throw new RuntimeException("Accessed Potions before Bootstrap!");
}
else
{
BLINDNESS = createType(MobEffects.BLINDNESS);
LUCKY = createType(MobEffects.LUCK);
UNLUCKY = createType(MobEffects.UNLUCK);
HASTE = createType(MobEffects.HASTE);
RESISTANCE = createType(MobEffects.RESISTANCE);
WITHER = createType(MobEffects.WITHER);
LEVITATION = createType(MobEffects.LEVITATION);
GLOWING = createType(MobEffects.GLOWING);
}
}
public static void init()
{
//Modded potion effects
PotionHelper.addMix(AWKWARD, ModItems.HUMUS, ModPotions.DEADLY.getPotionType());
PotionHelper.addMix(AWKWARD, ModItems.HUMUS, ModPotions.ZEN_HEART.getPotionType());
// PotionHelper.addMix(AWKWARD, ModItems.CHILLI, ModPotions.VIRUS_ONE.getPotionType());
// PotionHelper.addMix(AWKWARD, Items.ROTTEN_FLESH, ModPotions.UNDYING.getPotionType());
//-----------------------------Types
}
static ModPotionType createType(Potion potion)
{
//mostly for vanilla
return new ModPotionType(potion.getName(), getEffect(potion));
}
public static PotionEffect getEffect(Potion potion)
{
return new PotionEffect(potion, potion.isBadEffect() ? 1800 : 3600);
}
}
6.在resources包中的lang文件中添加我们所有药水效果的名称
en_us.lang
中添加:
#Potions
rejoymod.potion.zen_heart=Virus Power
#rejoymod.potion.burn=E Decay
#rejoymod.potion.erosion=Erosion Biohazard
在textures\misc中添加我们potions贴图,名称为potions.png(第一步中的ResourceLocation)
我们的potions图片(可直接下载),从第二行最左边开始第一个icon(0号)开始,往右依次加1作为其序号:
7.保存项目 -> 启动游戏调试
我们可以用指令来给予自己的buff效果:
/effect @p modid:buff名称
以/effect @p rejoymod:zen_heart
为例: