添加烟雾染色配方

This commit is contained in:
17146 2025-07-07 19:57:39 +08:00 committed by Light_Quanta
parent 6700db1869
commit 8849199f6e
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
6 changed files with 192 additions and 6 deletions

View file

@ -0,0 +1,4 @@
{
"type": "superbwarfare:smoke_dye",
"category": "misc"
}

View file

@ -8,6 +8,7 @@ import com.atsuishio.superbwarfare.item.ContainerBlockItem;
import com.atsuishio.superbwarfare.recipe.AmmoBoxAddAmmoRecipe;
import com.atsuishio.superbwarfare.recipe.AmmoBoxExtractAmmoRecipe;
import com.atsuishio.superbwarfare.recipe.PotionMortarShellRecipe;
import com.atsuishio.superbwarfare.recipe.SmokeDyeRecipe;
import net.minecraft.core.HolderLookup;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.data.PackOutput;
@ -36,6 +37,7 @@ public class ModRecipeProvider extends RecipeProvider {
SpecialRecipeBuilder.special(PotionMortarShellRecipe::new).save(writer, "potion_mortar_shell");
SpecialRecipeBuilder.special(AmmoBoxAddAmmoRecipe::new).save(writer, "ammo_box_add_ammo");
SpecialRecipeBuilder.special(AmmoBoxExtractAmmoRecipe::new).save(writer, "ammo_box_extract_ammo");
SpecialRecipeBuilder.special(SmokeDyeRecipe::new).save(writer, "smoke_dye");
// items
// 材料

View file

@ -35,9 +35,14 @@ import software.bernie.geckolib.animation.AnimatableManager;
import software.bernie.geckolib.util.GeckoLibUtil;
public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements GeoEntity {
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private int count = 8;
private int fuse = 100;
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private float rColor = 1.0f;
private float gColor = 1.0f;
private float bColor = 1.0f;
public M18SmokeGrenadeEntity(EntityType<? extends M18SmokeGrenadeEntity> type, Level world) {
super(type, world);
@ -60,6 +65,9 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
super.addAdditionalSaveData(pCompound);
pCompound.putFloat("Fuse", this.fuse);
pCompound.putInt("Count", this.count);
pCompound.putFloat("RColor", this.rColor);
pCompound.putFloat("GColor", this.gColor);
pCompound.putFloat("BColor", this.bColor);
}
@Override
@ -71,6 +79,15 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
if (pCompound.contains("Count")) {
this.count = Mth.clamp(pCompound.getInt("Count"), 1, 64);
}
if (pCompound.contains("RColor")) {
this.rColor = pCompound.getFloat("RColor");
}
if (pCompound.contains("GColor")) {
this.gColor = pCompound.getFloat("GColor");
}
if (pCompound.contains("BColor")) {
this.bColor = pCompound.getFloat("BColor");
}
}
@Override
@ -160,7 +177,7 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
if (fuse <= 0 && tickCount % 2 == 0) {
if (this.level() instanceof ServerLevel serverLevel) {
ParticleTool.sendParticle(serverLevel, new CustomSmokeOption(1, 1, 1), this.getX(), this.getY() + getBbHeight(), this.getZ(),
ParticleTool.sendParticle(serverLevel, new CustomSmokeOption(this.rColor, this.gColor, this.bColor), this.getX(), this.getY() + getBbHeight(), this.getZ(),
8, 0.075, 0.01, 0.075, 0.08, true);
}
}
@ -196,4 +213,22 @@ public class M18SmokeGrenadeEntity extends ThrowableItemProjectile implements Ge
return 0.07F;
}
public float getRed() {
return rColor;
}
public float getGreen() {
return gColor;
}
public float getBlue() {
return bColor;
}
public M18SmokeGrenadeEntity setColor(float r, float g, float b) {
this.rColor = r;
this.gColor = g;
this.bColor = b;
return this;
}
}

View file

@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.recipe.AmmoBoxAddAmmoRecipe;
import com.atsuishio.superbwarfare.recipe.AmmoBoxExtractAmmoRecipe;
import com.atsuishio.superbwarfare.recipe.PotionMortarShellRecipe;
import com.atsuishio.superbwarfare.recipe.SmokeDyeRecipe;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.item.crafting.SimpleCraftingRecipeSerializer;
@ -22,4 +23,7 @@ public class ModRecipes {
RECIPE_SERIALIZERS.register("ammo_box_add_ammo", () -> new SimpleCraftingRecipeSerializer<>(AmmoBoxAddAmmoRecipe::new));
public static final DeferredHolder<RecipeSerializer<?>, SimpleCraftingRecipeSerializer<AmmoBoxExtractAmmoRecipe>> AMMO_BOX_EXTRACT_AMMO_SERIALIZER =
RECIPE_SERIALIZERS.register("ammo_box_extract_ammo", () -> new SimpleCraftingRecipeSerializer<>(AmmoBoxExtractAmmoRecipe::new));
public static final DeferredHolder<RecipeSerializer<?>, RecipeSerializer<SmokeDyeRecipe>> SMOKE_DYE_SERIALIZER =
RECIPE_SERIALIZERS.register("smoke_dye", () -> new SimpleCraftingRecipeSerializer<>(SmokeDyeRecipe::new));
}

View file

@ -28,12 +28,12 @@ import java.util.List;
public class M18SmokeGrenade extends Item implements ProjectileItem {
public static final String TAG_COLOR = "Color";
public M18SmokeGrenade() {
super(new Properties().rarity(Rarity.UNCOMMON));
}
public static final String TAG_COLOR = "Color";
public void setColor(ItemStack stack, int color) {
NBTTool.getTag(stack).putInt(TAG_COLOR, color);
}
@ -77,7 +77,10 @@ public class M18SmokeGrenade extends Item implements ProjectileItem {
player.getCooldowns().addCooldown(stack.getItem(), 20);
float power = Math.min(usingTime / 8f, 1.8f);
M18SmokeGrenadeEntity grenade = new M18SmokeGrenadeEntity(player, worldIn, 80 - usingTime);
int color = this.getColor(stack);
M18SmokeGrenadeEntity grenade = new M18SmokeGrenadeEntity(player, worldIn, 80 - usingTime)
.setColor((color >> 16 & 255) / 255f, ((color >> 8) & 255) / 255f, (color & 255) / 255f);
grenade.shootFromRotation(player, player.getXRot(), player.getYRot(), 0, power, 0);
worldIn.addFreshEntity(grenade);
@ -96,7 +99,9 @@ public class M18SmokeGrenade extends Item implements ProjectileItem {
@ParametersAreNonnullByDefault
public @NotNull ItemStack finishUsingItem(ItemStack pStack, Level pLevel, LivingEntity pLivingEntity) {
if (!pLevel.isClientSide) {
M18SmokeGrenadeEntity grenade = new M18SmokeGrenadeEntity(pLivingEntity, pLevel, 2);
int color = this.getColor(pStack);
M18SmokeGrenadeEntity grenade = new M18SmokeGrenadeEntity(pLivingEntity, pLevel, 2)
.setColor((color >> 16 & 255) / 255f, ((color >> 8) & 255) / 255f, (color & 255) / 255f);
pLevel.addFreshEntity(grenade);
if (pLivingEntity instanceof Player player) {

View file

@ -0,0 +1,136 @@
package com.atsuishio.superbwarfare.recipe;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModRecipes;
import com.atsuishio.superbwarfare.item.M18SmokeGrenade;
import com.google.common.collect.Lists;
import net.minecraft.core.HolderLookup;
import net.minecraft.util.FastColor;
import net.minecraft.world.item.DyeItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.crafting.CraftingBookCategory;
import net.minecraft.world.item.crafting.CraftingInput;
import net.minecraft.world.item.crafting.CustomRecipe;
import net.minecraft.world.item.crafting.RecipeSerializer;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
public class SmokeDyeRecipe extends CustomRecipe {
public SmokeDyeRecipe(CraftingBookCategory pCategory) {
super(pCategory);
}
@Override
public boolean matches(@NotNull CraftingInput input, @NotNull Level pLevel) {
ItemStack itemstack = ItemStack.EMPTY;
List<ItemStack> list = Lists.newArrayList();
for (var stack : input.items()) {
if (stack.isEmpty()) continue;
if (stack.is(ModItems.M18_SMOKE_GRENADE.get())) {
if (!itemstack.isEmpty()) {
return false;
}
itemstack = stack;
} else {
if (!(stack.getItem() instanceof DyeItem)) {
return false;
}
list.add(stack);
}
}
return !itemstack.isEmpty() && !list.isEmpty();
}
@Override
@ParametersAreNonnullByDefault
public @NotNull ItemStack assemble(CraftingInput input, HolderLookup.Provider registries) {
List<DyeItem> list = Lists.newArrayList();
ItemStack itemstack = ItemStack.EMPTY;
for (var stack : input.items()) {
if (!stack.isEmpty()) {
var item = stack.getItem();
if (stack.is(ModItems.M18_SMOKE_GRENADE.get())) {
if (!itemstack.isEmpty()) {
return ItemStack.EMPTY;
}
itemstack = stack.copy();
} else {
if (!(item instanceof DyeItem dyeItem)) {
return ItemStack.EMPTY;
}
list.add(dyeItem);
}
}
}
return !itemstack.isEmpty() && !list.isEmpty() ? dyeItem(itemstack, list) : ItemStack.EMPTY;
}
@Override
public boolean canCraftInDimensions(int pWidth, int pHeight) {
return pWidth * pHeight >= 2;
}
@Override
public @NotNull RecipeSerializer<?> getSerializer() {
return ModRecipes.SMOKE_DYE_SERIALIZER.get();
}
public static ItemStack dyeItem(ItemStack pStack, List<DyeItem> pDyes) {
ItemStack itemstack;
int[] colors = new int[3];
int i = 0;
int j = 0;
if (pStack.getItem() instanceof M18SmokeGrenade grenade) {
itemstack = pStack.copyWithCount(1);
int color = grenade.getColor(pStack);
if (color != 0xFFFFFF) {
float r = (float) (color >> 16 & 255) / 255.0F;
float g = (float) (color >> 8 & 255) / 255.0F;
float b = (float) (color & 255) / 255.0F;
i += (int) (Math.max(r, Math.max(g, b)) * 255.0F);
colors[0] += (int) (r * 255.0F);
colors[1] += (int) (g * 255.0F);
colors[2] += (int) (b * 255.0F);
++j;
}
for (DyeItem dyeitem : pDyes) {
var dyeColors = dyeitem.getDyeColor().getTextureDiffuseColor();
int r = FastColor.ARGB32.red(dyeColors);
int g = FastColor.ARGB32.green(dyeColors);
int b = FastColor.ARGB32.blue(dyeColors);
i += Math.max(r, Math.max(g, b));
colors[0] += r;
colors[1] += g;
colors[2] += b;
++j;
}
} else {
return ItemStack.EMPTY;
}
int red = colors[0] / j;
int green = colors[1] / j;
int blue = colors[2] / j;
float rate = (float) i / (float) j;
float max = (float) Math.max(red, Math.max(green, blue));
red = (int) ((float) red * rate / max);
green = (int) ((float) green * rate / max);
blue = (int) ((float) blue * rate / max);
int color = (red << 8) + green;
color = (color << 8) + blue;
grenade.setColor(itemstack, color);
return itemstack;
}
}