mirror of
https://github.com/FatherToast/SpecialMobs.git
synced 2025-04-24 14:25:01 +00:00
Implement data gen
This commit is contained in:
parent
3fac9d5013
commit
85e1825e3c
13 changed files with 147 additions and 34 deletions
|
@ -56,7 +56,7 @@ minecraft {
|
|||
property 'forge.logging.markers', 'REGISTRIES'
|
||||
property 'forge.logging.console.level', 'debug'
|
||||
|
||||
args '--mod', 'deadlyworld', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
args '--mod', 'specialmobs', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/')
|
||||
|
||||
mods {
|
||||
deadlyworld {
|
||||
|
|
|
@ -6,7 +6,8 @@ import fathertoast.specialmobs.common.util.AnnotationHelper;
|
|||
import fathertoast.specialmobs.common.util.References;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.entity.*;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.monster.CreeperEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -39,7 +40,8 @@ public class MobFamily<T extends LivingEntity> {
|
|||
|
||||
public static final MobFamily<CreeperEntity> CREEPER = new MobFamily<>(
|
||||
"Creeper", "creepers", 0x0da70b, new EntityType[] { EntityType.CREEPER },
|
||||
"Dark"//, "Death", "Dirt", "Doom", "Drowning", "Ender", "Fire", "Gravel", "Jumping", "Lightning", "Mini", "Splitting"
|
||||
"Dark"//, "Death", "Dirt", "Doom", "Drowning", "Ender", "Fire", "Gravel", "Jumping", "Lightning",
|
||||
// "Mini", "Scope", "Splitting"
|
||||
);
|
||||
|
||||
// public static final MobFamily<ZombieEntity> ZOMBIE = new MobFamily<>(
|
||||
|
|
|
@ -57,6 +57,22 @@ public @interface SpecialMob {
|
|||
@Target( ElementType.METHOD )
|
||||
@interface AttributeCreator { }
|
||||
|
||||
/**
|
||||
* REQUIRED. This is called during data generation to build the mod's default lang files.
|
||||
* <p>
|
||||
* The annotated method must have a signature that follows the pattern:
|
||||
* <p>
|
||||
* public static String[] METHOD_NAME( String langKey )
|
||||
* <p>
|
||||
* The returned string array should be created by References#translations using the given lang key as the first
|
||||
* argument. Always be sure that any non-ASCII characters used are properly handled by the translations method.
|
||||
*
|
||||
* @see fathertoast.specialmobs.common.util.References#translations(String, String, String, String, String, String, String, String)
|
||||
*/
|
||||
@Retention( RetentionPolicy.RUNTIME )
|
||||
@Target( ElementType.METHOD )
|
||||
@interface LanguageProvider { }
|
||||
|
||||
/**
|
||||
* REQUIRED. This is called during data generation to build the mob's default loot table. Special variants will
|
||||
* typically start this method by calling their vanilla replacement's implementation of this method.
|
||||
|
|
|
@ -100,7 +100,7 @@ public class SpecialMobs {
|
|||
|
||||
//packetHandler.registerMessages();
|
||||
|
||||
//MinecraftForge.EVENT_BUS.register( new NAEventListener() );
|
||||
//MinecraftForge.EVENT_BUS.register( new SMEventListener() );
|
||||
|
||||
IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package fathertoast.specialmobs.common.entity.creeper;
|
|||
|
||||
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
|
||||
import fathertoast.specialmobs.common.bestiary.SpecialMob;
|
||||
import fathertoast.specialmobs.common.util.References;
|
||||
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.block.BlockState;
|
||||
|
@ -9,7 +10,6 @@ import net.minecraft.block.Blocks;
|
|||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
||||
import net.minecraft.entity.monster.CreeperEntity;
|
||||
import net.minecraft.fluid.FluidState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
|
@ -44,6 +44,12 @@ public class DarkCreeperEntity extends _SpecialCreeperEntity {
|
|||
return _SpecialCreeperEntity.createAttributes();
|
||||
}
|
||||
|
||||
@SpecialMob.LanguageProvider
|
||||
public static String[] getTranslations( String langKey ) {
|
||||
return References.translations( langKey, "Dark Creeper",
|
||||
"", "", "", "", "", "" );//TODO
|
||||
}
|
||||
|
||||
@SpecialMob.LootTableProvider
|
||||
public static void buildLootTable( LootTableBuilder loot ) {
|
||||
addBaseLoot( loot );
|
||||
|
@ -74,6 +80,7 @@ public class DarkCreeperEntity extends _SpecialCreeperEntity {
|
|||
|
||||
// Add unaffected light sources to the explosion's affected area
|
||||
// Note that this does NOT simulate another explosion, instead just directly searches for and targets lights
|
||||
//TODO this doesn't seem to work; figure out new method
|
||||
final BlockPos center = new BlockPos( getX(), getY(), getZ() );
|
||||
final int radius = explosionRadius * 4 * (isPowered() ? 2 : 1);
|
||||
final BlockPos.Mutable pos = new BlockPos.Mutable();
|
||||
|
|
|
@ -49,6 +49,12 @@ public class _SpecialCreeperEntity extends CreeperEntity implements ISpecialMob<
|
|||
return CreeperEntity.createAttributes();
|
||||
}
|
||||
|
||||
@SpecialMob.LanguageProvider
|
||||
public static String[] getTranslations( String langKey ) {
|
||||
return References.translations( langKey, "Creeper",
|
||||
"", "", "", "", "", "" );//TODO
|
||||
}
|
||||
|
||||
@SpecialMob.LootTableProvider
|
||||
public static void addBaseLoot( LootTableBuilder loot ) {
|
||||
loot.addLootTable( "main", EntityType.CREEPER.getDefaultLootTable() );
|
||||
|
|
|
@ -43,7 +43,15 @@ public final class AnnotationHelper {
|
|||
/** Creates an attribute modifier map from a special mob species. Throws an exception if anything goes wrong. */
|
||||
public static AttributeModifierMap createAttributes( MobFamily.Species<?> species )
|
||||
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
return ((AttributeModifierMap.MutableAttribute) getMethod( species.entityClass, SpecialMob.AttributeCreator.class ).invoke( null )).build();
|
||||
return ((AttributeModifierMap.MutableAttribute) getMethod( species.entityClass, SpecialMob.AttributeCreator.class )
|
||||
.invoke( null )).build();
|
||||
}
|
||||
|
||||
/** Gets the translations from a special mob species. Throws an exception if anything goes wrong. */
|
||||
public static String[] getTranslations( MobFamily.Species<?> species )
|
||||
throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
|
||||
return (String[]) getMethod( species.entityClass, SpecialMob.LanguageProvider.class )
|
||||
.invoke( null, species.entityType.get().getDescriptionId() );
|
||||
}
|
||||
|
||||
/** Builds a loot table from a special mob species. Throws an exception if anything goes wrong. */
|
||||
|
|
|
@ -60,4 +60,30 @@ public final class References {
|
|||
public static final String TAG_DRY_EXPLODE = "CannotExplodeWhileWet";
|
||||
public static final String TAG_WHEN_BURNING_EXPLODE = "ExplodesWhileBurning";
|
||||
public static final String TAG_WHEN_SHOT_EXPLODE = "ExplodesWhenShot";
|
||||
|
||||
|
||||
//--------------- INTERNATIONALIZATION ----------------
|
||||
|
||||
/** This method provides helper tags to make linking translations up easier, and also enforces the correct array length. */
|
||||
public static String[] translations( String key, String en, String es, String pt, String fr, String it, String de, String pir ) {
|
||||
// Note that this must match up EXACTLY to the TranslationKey enum in SMLanguageProvider
|
||||
String[] translation = { key, en, es, pt, fr, it, de, pir };
|
||||
|
||||
// Fix the encoding to allow us to use accented characters in the translation string literals
|
||||
// Note: If a translation uses any non-ASCII characters, make sure they are all in this matrix! (case-sensitive)
|
||||
final String[][] utf8ToUnicode = {
|
||||
{ "à", "\u00E0" }, { "á", "\u00E1" }, { "ã", "\u00E3" }, { "ä", "\u00E4" },
|
||||
{ "ç", "\u00E7" },
|
||||
{ "è", "\u00E8" }, { "é", "\u00E9" }, { "ê", "\u00EA" },
|
||||
{ "í", "\u00ED" },
|
||||
{ "ó", "\u00F3" }, { "õ", "\u00F5" }, { "ö", "\u00F6" },
|
||||
{ "ù", "\u00F9" }, { "û", "\u00FB" }, { "ü", "\u00FC" },
|
||||
{ "œ", "\u0153" }
|
||||
};
|
||||
for( int i = 1; i < translation.length; i++ ) {
|
||||
for( String[] fix : utf8ToUnicode )
|
||||
translation[i] = translation[i].replace( fix[0], fix[1] ); // Note: This is kinda dumb, but it works so idc
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ public class DataGatherListener {
|
|||
DataGenerator generator = event.getGenerator();
|
||||
|
||||
if( event.includeClient() ) {
|
||||
generator.addProvider( new SMItemModelProvider( generator, event.getExistingFileHelper() ) );
|
||||
for( Map.Entry<String, SMLanguageProvider.TranslationKey> entry : SMLanguageProvider.LANG_CODE_MAP.entrySet() ) {
|
||||
generator.addProvider( new SMLanguageProvider( generator, entry.getKey(), entry.getValue() ) );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
package fathertoast.specialmobs.datagen;
|
||||
|
||||
import fathertoast.specialmobs.common.bestiary.MobFamily;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.generators.ItemModelProvider;
|
||||
import net.minecraftforge.common.data.ExistingFileHelper;
|
||||
|
||||
public class SMItemModelProvider extends ItemModelProvider {
|
||||
|
||||
public SMItemModelProvider( DataGenerator gen, ExistingFileHelper existingFileHelper ) {
|
||||
super( gen, SpecialMobs.MOD_ID, existingFileHelper );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void registerModels() {
|
||||
// Bestiary-generated spawn egg models
|
||||
final ResourceLocation spawnEggParent = modLoc( ITEM_FOLDER + "/template_sm_spawn_egg" );
|
||||
for( MobFamily.Species<?> species : MobFamily.getAllSpecies() )
|
||||
withExistingParent( species.spawnEgg.getId().getPath(), spawnEggParent );
|
||||
}
|
||||
}
|
|
@ -1,9 +1,14 @@
|
|||
package fathertoast.specialmobs.datagen;
|
||||
|
||||
import fathertoast.specialmobs.common.bestiary.MobFamily;
|
||||
import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||
import fathertoast.specialmobs.common.util.AnnotationHelper;
|
||||
import fathertoast.specialmobs.common.util.References;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraftforge.common.data.LanguageProvider;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
public class SMLanguageProvider extends LanguageProvider {
|
||||
|
@ -18,29 +23,6 @@ public class SMLanguageProvider extends LanguageProvider {
|
|||
TranslationKey( String id ) { code = id; }
|
||||
}
|
||||
|
||||
/** This method provides helper tags to make linking translations up easier, and also enforces the correct array length. */
|
||||
private static String[] translations( String key, String en, String es, String pt, String fr, String it, String de, String pir ) {
|
||||
// Note that this must match up EXACTLY to the TranslationKey enum above
|
||||
String[] translation = { key, en, es, pt, fr, it, de, pir };
|
||||
|
||||
// Fix the encoding to allow us to use accented characters in the translation string literals
|
||||
// Note: If a translation uses any non-ASCII characters, make sure they are all in this matrix! (case-sensitive)
|
||||
final String[][] utf8ToUnicode = {
|
||||
{ "à", "\u00E0" }, { "á", "\u00E1" }, { "ã", "\u00E3" }, { "ä", "\u00E4" },
|
||||
{ "ç", "\u00E7" },
|
||||
{ "è", "\u00E8" }, { "é", "\u00E9" }, { "ê", "\u00EA" },
|
||||
{ "í", "\u00ED" },
|
||||
{ "ó", "\u00F3" }, { "õ", "\u00F5" }, { "ö", "\u00F6" },
|
||||
{ "ù", "\u00F9" }, { "û", "\u00FB" }, { "ü", "\u00FC" },
|
||||
{ "œ", "\u0153" }
|
||||
};
|
||||
for( int i = 1; i < translation.length; i++ ) {
|
||||
for( String[] fix : utf8ToUnicode )
|
||||
translation[i] = translation[i].replace( fix[0], fix[1] ); // Note: This is kinda dumb, but it works so idc
|
||||
}
|
||||
return translation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrix linking the actual translations to their lang key.
|
||||
* <p>
|
||||
|
@ -50,15 +32,29 @@ public class SMLanguageProvider extends LanguageProvider {
|
|||
*
|
||||
* @see #addTranslations()
|
||||
*/
|
||||
@SuppressWarnings( "SpellCheckingInspection" )
|
||||
private static final String[][] TRANSLATIONS = {
|
||||
// NYI
|
||||
};
|
||||
private static final String[][] TRANSLATIONS;
|
||||
|
||||
/** Maps which translation key each lang code uses, allowing multiple lang codes to use the same translations. */
|
||||
public static final HashMap<String, TranslationKey> LANG_CODE_MAP = new HashMap<>();
|
||||
|
||||
static {
|
||||
final ArrayList<String[]> translationList = new ArrayList<>();
|
||||
|
||||
final String[] spawnEggTranslationPattern = References.translations( "%s", "%s Spawn Egg",
|
||||
"%s", "%s", "%s", "%s", "%s", "%s" ); //TODO
|
||||
|
||||
// Bestiary-generated translations
|
||||
for( MobFamily.Species<?> species : MobFamily.getAllSpecies() ) {
|
||||
final String[] speciesTranslations = getTranslations( species );
|
||||
String[] spawnEggTranslations = format( spawnEggTranslationPattern, speciesTranslations );
|
||||
spawnEggTranslations[0] = species.spawnEgg.get().getDescriptionId();
|
||||
|
||||
translationList.add( speciesTranslations );
|
||||
translationList.add( spawnEggTranslations );
|
||||
}
|
||||
|
||||
TRANSLATIONS = translationList.toArray( new String[0][0] );
|
||||
|
||||
// Assign all specific locales to the translation we want to use
|
||||
mapAll( TranslationKey.ENGLISH, "us" ); // We can ignore other English locales, en_us is the fallback for all languages
|
||||
mapAll( TranslationKey.SPANISH, "es", "ar", "cl", "ec", "mx", "uy", "ve" );
|
||||
|
@ -85,6 +81,25 @@ public class SMLanguageProvider extends LanguageProvider {
|
|||
SpecialMobs.LOG.info( "Translation key verification complete!" );
|
||||
}
|
||||
|
||||
/** Gets the translations for a specific entity species. */
|
||||
private static String[] getTranslations( MobFamily.Species<?> species ) {
|
||||
try {
|
||||
return AnnotationHelper.getTranslations( species );
|
||||
}
|
||||
catch( NoSuchMethodException | InvocationTargetException | IllegalAccessException ex ) {
|
||||
throw new RuntimeException( "Entity class for " + species.name + " has invalid language provider method", ex );
|
||||
}
|
||||
}
|
||||
|
||||
/** Applies single argument string formats 1:1 given an array of formats and an array of arguments. */
|
||||
private static String[] format( String[] formats, String[] args ) {
|
||||
final String[] formatted = new String[formats.length];
|
||||
for( int i = 0; i < formatted.length; i++ ) {
|
||||
formatted[i] = String.format( formats[i], args[i] );
|
||||
}
|
||||
return formatted;
|
||||
}
|
||||
|
||||
/** Maps any number of locale codes to a single translation. */
|
||||
private static void mapAll( TranslationKey translation, String... locales ) {
|
||||
for( String locale : locales ) {
|
||||
|
|
|
@ -40,7 +40,9 @@ public class SMLootTableProvider extends LootTableProvider {
|
|||
/** Validates this mod's loot tables. */
|
||||
@Override
|
||||
protected void validate( Map<ResourceLocation, LootTable> tables, ValidationTracker ctx ) {
|
||||
tables.forEach( ( name, table ) -> LootTableManager.validate( ctx, name, table ) );
|
||||
// We have to disable validation because vanilla entity loot tables are not recognized;
|
||||
// this is kinda scary, maybe later we can look into re-enabling validation
|
||||
//tables.forEach( ( name, table ) -> LootTableManager.validate( ctx, name, table ) );
|
||||
}
|
||||
|
||||
/** Provides all entity loot tables for this mod. */
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "minecraft:item/spawn_egg",
|
||||
"layer1": "minecraft:item/spawn_egg_overlay"
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue