Last active
October 22, 2023 04:40
-
-
Save aksource/9be70a0bef9a46eec468 to your computer and use it in GitHub Desktop.
TextureStitchEvent利用。これで大体の需要は満たせてるかな?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.examplemod; | |
import com.google.common.base.Function; | |
import com.google.common.collect.ImmutableMap; | |
import net.minecraft.block.Block; | |
import net.minecraft.block.BlockColored; | |
import net.minecraft.block.material.Material; | |
import net.minecraft.block.state.IBlockState; | |
import net.minecraft.client.Minecraft; | |
import net.minecraft.client.renderer.block.model.BakedQuad; | |
import net.minecraft.client.renderer.block.model.ItemCameraTransforms; | |
import net.minecraft.client.renderer.block.statemap.StateMapperBase; | |
import net.minecraft.client.renderer.texture.TextureAtlasSprite; | |
import net.minecraft.client.renderer.texture.TextureMap; | |
import net.minecraft.client.resources.model.IBakedModel; | |
import net.minecraft.client.resources.model.ModelResourceLocation; | |
import net.minecraft.creativetab.CreativeTabs; | |
import net.minecraft.item.EnumDyeColor; | |
import net.minecraft.item.Item; | |
import net.minecraft.item.ItemCloth; | |
import net.minecraft.item.ItemStack; | |
import net.minecraft.util.EnumFacing; | |
import net.minecraft.util.ResourceLocation; | |
import net.minecraftforge.client.event.ModelBakeEvent; | |
import net.minecraftforge.client.event.TextureStitchEvent; | |
import net.minecraftforge.client.model.*; | |
import net.minecraftforge.common.MinecraftForge; | |
import net.minecraftforge.fml.common.Mod; | |
import net.minecraftforge.fml.common.Mod.EventHandler; | |
import net.minecraftforge.fml.common.event.FMLInitializationEvent; | |
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; | |
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; | |
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; | |
import net.minecraftforge.fml.common.registry.GameRegistry; | |
import net.minecraftforge.fml.relauncher.Side; | |
import net.minecraftforge.fml.relauncher.SideOnly; | |
import java.io.IOException; | |
import java.util.ArrayList; | |
import java.util.List; | |
@Mod(modid = SampleBlockTexChgMod.MOD_ID, name = "HogeHoge", version = "1.0", dependencies = "required-after:Forge@[1.8.9-11.15.1.1764,)", useMetadata = true) | |
public class SampleBlockTexChgMod { | |
/** | |
* ModId文字列 | |
*/ | |
public static final String MOD_ID = "sampleblocktexchgmod"; | |
/** | |
* サンプルブロックのインスタンス | |
*/ | |
private static Block sampleBlock; | |
/** | |
* ブロック描画用 | |
*/ | |
private static ModelResourceLocation normalMRL; | |
/** | |
* インベントリ描画用 | |
*/ | |
private static ModelResourceLocation inventoryMRL; | |
/** | |
* 羊毛テクスチャのリソロケ用 | |
*/ | |
private static List<ResourceLocation> coloredTexList = new ArrayList<>(); | |
/** | |
* MODで追加したテクスチャのRLインスタンス | |
* ファイルの場所は、assets/</modid>/textures/blocks/sample.png | |
*/ | |
private static ResourceLocation modTexRL = new ResourceLocation(MOD_ID.toLowerCase() + ":blocks/sample"); | |
@EventHandler | |
public void preInit(FMLPreInitializationEvent event) { | |
sampleBlock = new SampleTexChgBlock(); | |
if (event.getSide().isClient()) { | |
normalMRL = new ModelResourceLocation(sampleBlock.getRegistryName(), "normal"); | |
inventoryMRL = new ModelResourceLocation(sampleBlock.getRegistryName(), "inventory"); | |
/* リソロケ生成が面倒だからサボった */ | |
for (EnumDyeColor enumDyeColor : EnumDyeColor.values()) { | |
coloredTexList.add(new ResourceLocation("blocks/wool_colored_" + enumDyeColor.name().toLowerCase())); | |
/* ここで、インベントリ描画用のModelResourceLocationの登録が必要 */ | |
ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(sampleBlock), enumDyeColor.getMetadata(), inventoryMRL); | |
} | |
/* ここで、ブロック描画用のModelResourceLocationの登録が必要 */ | |
ModelLoader.setCustomStateMapper(sampleBlock, new StateMapperBase() { | |
@Override | |
protected ModelResourceLocation getModelResourceLocation(IBlockState state) { | |
/* すべてのstateに対して同じModelResourceLocationを指定。あとのEventで利用 */ | |
return normalMRL; | |
} | |
}); | |
} | |
} | |
@EventHandler | |
public void init(FMLInitializationEvent event) { | |
if (event.getSide().isClient()) { | |
/* ModelBakeEvent登録 */ | |
MinecraftForge.EVENT_BUS.register(this); | |
} | |
} | |
@EventHandler | |
public void postInit(FMLPostInitializationEvent event) { | |
/* すまんな、テンプレートなんだ。 */ | |
} | |
@SubscribeEvent | |
public void onBakingModelEvent(ModelBakeEvent event) { | |
/* 形状のパクリ元 */ | |
ResourceLocation rl = new ResourceLocation("block/cactus"); | |
try { | |
/* パクリ元のIModelを取得。注意:ModelResourceLocationでも取れるが、IRetexturableModelではない。 */ | |
IModel model = event.modelLoader.getModel(rl); | |
if (model instanceof IRetexturableModel) { | |
IBakedModel bakedModel = new SampleRetexturedBakedModel((IRetexturableModel) model); | |
/* ブロック描画用モデルのセット。ISmartBlockModel継承のものが良い。 */ | |
event.modelRegistry.putObject(normalMRL, bakedModel); | |
/* インベントリ描画用のモデルのセット。ISmartItemModel継承のものが良い */ | |
event.modelRegistry.putObject(inventoryMRL, bakedModel); | |
} | |
} catch (IOException e) { | |
/* モデル指定がミスるとここに飛ぶ */ | |
e.printStackTrace(); | |
} | |
} | |
@SubscribeEvent | |
public void textureStitch(TextureStitchEvent.Pre event) { | |
TextureMap textureMap = event.map; | |
/* JSONで指定していないテクスチャはこのタイミングで登録する。 */ | |
textureMap.registerSprite(modTexRL); | |
} | |
/** | |
* サンプルブロッククラス。色付きブロック継承 | |
*/ | |
private static class SampleTexChgBlock extends BlockColored { | |
public SampleTexChgBlock() { | |
super(Material.ground); | |
/* ここらへんは、いいよね? */ | |
this.setRegistryName("sample_tex_chg_block"); | |
GameRegistry.registerBlock(this, ItemCloth.class); | |
this.setCreativeTab(CreativeTabs.tabBlock); | |
this.setUnlocalizedName("sample_tex_chg_block"); | |
} | |
} | |
@SideOnly(Side.CLIENT) | |
private static class SampleRetexturedBakedModel implements ISmartBlockModel, ISmartItemModel { | |
private final IRetexturableModel retexturableModel; | |
/* bakeメソッドで必要。staticなクラスに置いても良いと思う。 */ | |
private Function<ResourceLocation, TextureAtlasSprite> textureGetter = new Function<ResourceLocation, TextureAtlasSprite>() { | |
public TextureAtlasSprite apply(ResourceLocation location) { | |
return Minecraft.getMinecraft().getTextureMapBlocks().getAtlasSprite(location.toString()); | |
} | |
}; | |
public SampleRetexturedBakedModel(IRetexturableModel model) { | |
retexturableModel = model; | |
} | |
@Override | |
public IBakedModel handleItemState(ItemStack stack) { | |
/* retextureメソッドで、JSONで指定したテクスチャを入れ替えてモデルを生成できる。 | |
* 今回はsideに指定したテクスチャを羊毛テクスチャに入れ替え */ | |
return retexturableModel.retexture(ImmutableMap.of("side", coloredTexList.get(stack.getItemDamage() % 16).toString(), | |
"top", modTexRL.toString())) | |
.bake(retexturableModel.getDefaultState(), Attributes.DEFAULT_BAKED_FORMAT, textureGetter); | |
} | |
@Override | |
public IBakedModel handleBlockState(IBlockState state) { | |
/* retextureメソッドで、JSONで指定したテクスチャを入れ替えてモデルを生成できる。 | |
* 今回はsideに指定したテクスチャを羊毛テクスチャに入れ替え */ | |
return retexturableModel.retexture(ImmutableMap.of("side", coloredTexList.get(sampleBlock.getMetaFromState(state)).toString(), | |
"top", modTexRL.toString())).bake(retexturableModel.getDefaultState(), Attributes.DEFAULT_BAKED_FORMAT, textureGetter); | |
} | |
/* 以下、IBakedModelのメソッドだけど、handle~メソッドで違うモデルを返しているので、以下の状態で問題ない。 */ | |
@Override | |
public List<BakedQuad> getFaceQuads(EnumFacing facing) { | |
return null; | |
} | |
@Override | |
public List<BakedQuad> getGeneralQuads() { | |
return null; | |
} | |
@Override | |
public boolean isAmbientOcclusion() { | |
return false; | |
} | |
@Override | |
public boolean isGui3d() { | |
return false; | |
} | |
@Override | |
public boolean isBuiltInRenderer() { | |
return false; | |
} | |
@Override | |
public TextureAtlasSprite getParticleTexture() { | |
return null; | |
} | |
@Override | |
public ItemCameraTransforms getItemCameraTransforms() { | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment