Minecraft 1.12.2模组开发(四十) buff效果(Potion Effect)

今天我们在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)

cr4.jpg

我们的potions图片(可直接下载),从第二行最左边开始第一个icon(0号)开始,往右依次加1作为其序号:

potions.png

7.保存项目 -> 启动游戏调试

我们可以用指令来给予自己的buff效果:
/effect @p modid:buff名称
/effect @p rejoymod:zen_heart为例:
2022-04-05_16.39.33.png

可以看到我们的buff效果的确出现了,同时我们的生命回复效果在buff期间一直非常强。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jay_fearless

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值