tiny progress on witches

This commit is contained in:
FatherToast 2022-06-26 17:25:52 -05:00
parent 9180ec24e6
commit b90fcf9506
4 changed files with 280 additions and 11 deletions

View file

@ -1,10 +1,5 @@
package fathertoast.specialmobs.client;
import fathertoast.specialmobs.client.renderer.entity.SpecialCreeperRenderer;
import fathertoast.specialmobs.client.renderer.entity.SpecialSilverfishRenderer;
import fathertoast.specialmobs.client.renderer.entity.SpecialSkeletonRenderer;
import fathertoast.specialmobs.client.renderer.entity.SpecialSpiderRenderer;
import fathertoast.specialmobs.client.renderer.entity.SpecialZombieRenderer;
import fathertoast.specialmobs.client.renderer.entity.*;
import fathertoast.specialmobs.common.bestiary.MobFamily;
import fathertoast.specialmobs.common.core.SpecialMobs;
@ -43,6 +38,7 @@ public class ClientRegister {
registerFamilyRenderers( MobFamily.CAVE_SPIDER, SpecialSpiderRenderer::new );
registerFamilyRenderers( MobFamily.SILVERFISH, SpecialSilverfishRenderer::new );
registerFamilyRenderers( MobFamily.ENDERMAN, SpecialEndermanRenderer::new );
//registerFamilyRenderers( MobFamily.WITCH, SpecialWitchRenderer::new );
// Custom renderers
registerRenderer( NinjaSkeletonEntity.class, NinjaSkeletonRenderer::new );
@ -52,17 +48,14 @@ public class ClientRegister {
private static <T extends LivingEntity> void registerFamilyRenderers( MobFamily<T> family, IRenderFactory<? super T> renderFactory ) {
RenderingRegistry.registerEntityRenderingHandler( family.vanillaReplacement.entityType.get(), renderFactory );
for( MobFamily.Species<? extends T> species : family.variants )
//if( !species.hasCustomRenderer )
RenderingRegistry.registerEntityRenderingHandler( species.entityType.get(), renderFactory );
}
private static <T extends LivingEntity> void registerRenderer( Class<T> entityClass, IRenderFactory<? super T> renderFactory ) {
MobFamily.Species<T> species = MobFamily.findSpecies( entityClass );
if( species == null ) {
SpecialMobs.LOG.error( "Could not register renderer for entity class {}, as no belonging mob species was found.", entityClass.getSimpleName() );
return;
}
if( species == null )
throw new IllegalArgumentException( "Could not register renderer for entity class '" + entityClass.getSimpleName() + "', as no belonging mob species was found." );
RenderingRegistry.registerEntityRenderingHandler( species.entityType.get(), renderFactory );
}
}

View file

@ -0,0 +1,46 @@
package fathertoast.specialmobs.client.renderer.entity;
import com.mojang.blaze3d.matrix.MatrixStack;
import fathertoast.specialmobs.client.renderer.entity.layers.SpecialMobEyesLayer;
import fathertoast.specialmobs.client.renderer.entity.layers.SpecialMobOverlayLayer;
import fathertoast.specialmobs.common.entity.ISpecialMob;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.client.renderer.entity.WitchRenderer;
import net.minecraft.client.renderer.entity.model.WitchModel;
import net.minecraft.entity.monster.WitchEntity;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@OnlyIn( Dist.CLIENT )
public class SpecialWitchRenderer extends WitchRenderer {
private final float baseShadowRadius;
public SpecialWitchRenderer( EntityRendererManager rendererManager ) {
super( rendererManager );
baseShadowRadius = shadowRadius;
addLayer( new SpecialMobEyesLayer<>( this ) );
// Note: Overlay scaling only applies to base villager model
addLayer( new SpecialMobOverlayLayer<>( this, new WitchModel<>( 0.25F ) ) );
}
@Override
public ResourceLocation getTextureLocation( WitchEntity entity ) {
return ((ISpecialMob<?>) entity).getSpecialData().getTexture();
}
@Override
protected void scale( WitchEntity entity, MatrixStack matrixStack, float partialTick ) {
super.scale( entity, matrixStack, partialTick );
final float scale = ((ISpecialMob<?>) entity).getSpecialData().getRenderScale();
shadowRadius = baseShadowRadius * scale;
matrixStack.scale( scale, scale, scale );
}
}

View file

@ -93,7 +93,7 @@ public class MobFamily<T extends LivingEntity> {
// public static final MobFamily<WitchEntity> WITCH = new MobFamily<>(
// "Witch", "witches", 0x340000, new EntityType[] { EntityType.WITCH },
// "Domination", "Shadows", "Undead", "Wilds", "Wind"//Note - should wind be able to walk on water?
// "Domination"//, "Shadows", "Undead", "Wilds", "Wind"//Note - should wind be able to walk on water?
// );
// public static final MobFamily<GhastEntity> GHAST = new MobFamily<>(

View file

@ -0,0 +1,230 @@
package fathertoast.specialmobs.common.entity.witch;
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
import fathertoast.specialmobs.common.bestiary.SpecialMob;
import fathertoast.specialmobs.common.core.SpecialMobs;
import fathertoast.specialmobs.common.entity.ISpecialMob;
import fathertoast.specialmobs.common.entity.SpecialMobData;
import fathertoast.specialmobs.common.util.References;
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.block.BlockState;
import net.minecraft.entity.*;
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
import net.minecraft.entity.monster.WitchEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.projectile.SnowballEntity;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.network.datasync.DataSerializers;
import net.minecraft.network.datasync.EntityDataManager;
import net.minecraft.potion.EffectInstance;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@SpecialMob
public class _SpecialWitchEntity extends WitchEntity implements ISpecialMob<_SpecialWitchEntity> {
//--------------- Static Special Mob Hooks ----------------
@SpecialMob.BestiaryInfoSupplier
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
return new BestiaryInfo( 0xA80E0E );
}
@SpecialMob.AttributeCreator
public static AttributeModifierMap.MutableAttribute createAttributes() {
return WitchEntity.createAttributes();
}
@SpecialMob.LanguageProvider
public static String[] getTranslations( String langKey ) {
return References.translations( langKey, "Witch",
"", "", "", "", "", "" );//TODO
}
@SpecialMob.LootTableProvider
public static void addBaseLoot( LootTableBuilder loot ) {
loot.addLootTable( "main", EntityType.WITCH.getDefaultLootTable() );
}
@SpecialMob.Constructor
public _SpecialWitchEntity( EntityType<? extends _SpecialWitchEntity> entityType, World world ) {
super( entityType, world );
getSpecialData().initialize();
}
//--------------- Variant-Specific Breakouts ----------------
/** Called in the MobEntity.class constructor to initialize AI goals. */
@Override
protected void registerGoals() {
super.registerGoals();
registerVariantGoals();
}
/** Override to change this entity's AI goals. */
protected void registerVariantGoals() { }
/** Called when this entity successfully damages a target to apply on-hit effects. */
@Override
public void doEnchantDamageEffects( LivingEntity attacker, Entity target ) {
onVariantAttack( target );
super.doEnchantDamageEffects( attacker, target );
}
/** Override to apply effects when this entity hits a target with a melee attack. */
protected void onVariantAttack( Entity target ) { }
//TODO
/** Override to save data to this entity's NBT data. */
public void addVariantSaveData( CompoundNBT saveTag ) { }
/** Override to load data from this entity's NBT data. */
public void readVariantSaveData( CompoundNBT saveTag ) { }
//--------------- Family-Specific Implementations ----------------
/** The parameter for special mob render scale. */
private static final DataParameter<Float> SCALE = EntityDataManager.defineId( _SpecialWitchEntity.class, DataSerializers.FLOAT );
/** Called from the Entity.class constructor to define data watcher variables. */
@Override
protected void defineSynchedData() {
super.defineSynchedData();
specialData = new SpecialMobData<>( this, SCALE, 1.0F );
}
//TODO
//--------------- ISpecialMob Implementation ----------------
private SpecialMobData<_SpecialWitchEntity> specialData;
/** @return This mob's special data. */
@Override
public SpecialMobData<_SpecialWitchEntity> getSpecialData() { return specialData; }
/** @return The experience that should be dropped by this entity. */
@Override
public final int getExperience() { return xpReward; }
/** Sets the experience that should be dropped by this entity. */
@Override
public final void setExperience( int xp ) { xpReward = xp; }
static ResourceLocation GET_TEXTURE_PATH( String type ) {
return SpecialMobs.resourceLoc( SpecialMobs.TEXTURE_PATH + "witch/" + type + ".png" );
}
private static final ResourceLocation[] TEXTURES = {
new ResourceLocation( "textures/entity/witch.png" )
};
/** @return All default textures for this entity. */
@Override
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
//--------------- SpecialMobData Hooks ----------------
/** Called each tick to update this entity's movement. */
@Override
public void aiStep() {
super.aiStep();
getSpecialData().tick();
}
/** @return The eye height of this entity when standing. */
@Override
protected float getStandingEyeHeight( Pose pose, EntitySize size ) {
return super.getStandingEyeHeight( pose, size ) * getSpecialData().getBaseScale() * (isBaby() ? 0.53448F : 1.0F);
}
/** @return Whether this entity is immune to fire damage. */
@Override
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
/** Sets this entity on fire for a specific duration. */
@Override
public void setRemainingFireTicks( int ticks ) {
if( !getSpecialData().isImmuneToBurning() ) super.setRemainingFireTicks( ticks );
}
/** @return True if this entity can be leashed. */
@Override
public boolean canBeLeashed( PlayerEntity player ) { return !isLeashed() && getSpecialData().allowLeashing(); }
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
@Override
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
}
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
@Override
public boolean causeFallDamage( float distance, float damageMultiplier ) {
return super.causeFallDamage( distance, damageMultiplier * getSpecialData().getFallDamageMultiplier() );
}
/** @return True if this entity should NOT trigger pressure plates or tripwires. */
@Override
public boolean isIgnoringBlockTriggers() { return getSpecialData().ignorePressurePlates(); }
/** @return True if this entity can breathe underwater. */
@Override
public boolean canBreatheUnderwater() { return getSpecialData().canBreatheInWater(); }
/** @return True if this entity can be pushed by (flowing) fluids. */
@Override
public boolean isPushedByFluid() { return !getSpecialData().ignoreWaterPush(); }
/** @return True if this entity takes damage while wet. */
@Override
public boolean isSensitiveToWater() { return getSpecialData().isDamagedByWater(); }
/** @return Attempts to damage this entity; returns true if the hit was successful. */
@Override
public boolean hurt( DamageSource source, float amount ) {
if( isSensitiveToWater() && source.getDirectEntity() instanceof SnowballEntity ) {
amount = Math.max( 3.0F, amount );
}
return super.hurt( source, amount );
}
/** @return True if the effect can be applied to this entity. */
@Override
public boolean canBeAffected( EffectInstance effect ) { return getSpecialData().isPotionApplicable( effect ); }
/** Saves data to this entity's base NBT compound that is specific to its subclass. */
@Override
public void addAdditionalSaveData( CompoundNBT tag ) {
super.addAdditionalSaveData( tag );
final CompoundNBT saveTag = SpecialMobData.getSaveLocation( tag );
getSpecialData().writeToNBT( saveTag );
addVariantSaveData( saveTag );
}
/** Loads data from this entity's base NBT compound that is specific to its subclass. */
@Override
public void readAdditionalSaveData( CompoundNBT tag ) {
super.readAdditionalSaveData( tag );
final CompoundNBT saveTag = SpecialMobData.getSaveLocation( tag );
getSpecialData().readFromNBT( saveTag );
readVariantSaveData( saveTag );
}
}