Merge branch '1.16.5' of https://github.com/FatherToast/SpecialMobs into 1.16.5

This commit is contained in:
Sarinsa 2022-06-29 02:59:11 +02:00
commit 040b812d65
5 changed files with 154 additions and 1 deletions

View file

@ -40,7 +40,7 @@ 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", /*"Scope",*/ "Splitting"
"Mini", /*"Scope",*/ "Skeleton", "Splitting"
);
public static final MobFamily<ZombieEntity> ZOMBIE = new MobFamily<>(

View file

@ -14,6 +14,7 @@ import net.minecraft.entity.item.FallingBlockEntity;
import net.minecraft.item.Items;
import net.minecraft.util.DamageSource;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.MathHelper;
import net.minecraft.world.Explosion;
import net.minecraft.world.World;
@ -90,6 +91,8 @@ public class GravelCreeperEntity extends _SpecialCreeperEntity {
MathHelper.sin( yaw ) * speed );
level.addFreshEntity( gravel );
}
spawnAnim();
playSound( SoundEvents.GRAVEL_BREAK, 1.0F, 1.0F / (random.nextFloat() * 0.4F + 0.8F) );
}
/** @return Attempts to damage this entity; returns true if the hit was successful. */

View file

@ -0,0 +1,150 @@
package fathertoast.specialmobs.common.entity.creeper;
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
import fathertoast.specialmobs.common.bestiary.MobFamily;
import fathertoast.specialmobs.common.bestiary.SpecialMob;
import fathertoast.specialmobs.common.entity.ai.AIHelper;
import fathertoast.specialmobs.common.util.AttributeHelper;
import fathertoast.specialmobs.common.util.ExplosionHelper;
import fathertoast.specialmobs.common.util.References;
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.entity.CreatureAttribute;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
import net.minecraft.entity.ai.attributes.Attributes;
import net.minecraft.entity.ai.goal.FleeSunGoal;
import net.minecraft.entity.ai.goal.RestrictSunGoal;
import net.minecraft.entity.projectile.AbstractArrowEntity;
import net.minecraft.entity.projectile.ProjectileHelper;
import net.minecraft.inventory.EquipmentSlotType;
import net.minecraft.item.BowItem;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundEvents;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import javax.annotation.ParametersAreNonnullByDefault;
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@SpecialMob
public class SkeletonCreeperEntity extends _SpecialCreeperEntity {
//--------------- Static Special Mob Hooks ----------------
@SpecialMob.SpeciesReference
public static MobFamily.Species<SkeletonCreeperEntity> SPECIES;
@SpecialMob.BestiaryInfoSupplier
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
return new BestiaryInfo( 0xC1C1C1 );
//TODO theme - forest
}
@SpecialMob.AttributeCreator
public static AttributeModifierMap.MutableAttribute createAttributes() {
return AttributeHelper.of( _SpecialCreeperEntity.createAttributes() )
.addAttribute( Attributes.MAX_HEALTH, -4.0 )
.multAttribute( Attributes.MOVEMENT_SPEED, 1.2 )
.build();
}
@SpecialMob.LanguageProvider
public static String[] getTranslations( String langKey ) {
return References.translations( langKey, "Skeleton Creeper",
"", "", "", "", "", "" );//TODO
}
@SpecialMob.LootTableProvider
public static void buildLootTable( LootTableBuilder loot ) {
addBaseLoot( loot );
loot.addLootTable( "common", EntityType.SKELETON.getDefaultLootTable() );
}
@SpecialMob.Constructor
public SkeletonCreeperEntity( EntityType<? extends _SpecialCreeperEntity> entityType, World world ) {
super( entityType, world );
xpReward += 1;
}
//--------------- Variant-Specific Implementations ----------------
/** Override to change this entity's AI goals. */
@Override
protected void registerVariantGoals() {
AIHelper.insertGoal( goalSelector, 3, new FleeSunGoal( this, 1.0 ) );
AIHelper.insertGoal( goalSelector, 3, new RestrictSunGoal( this ) );
}
/** Override to change this creeper's explosion power multiplier. */
protected float getVariantExplosionPower( float radius ) { return super.getVariantExplosionPower( radius / 2.0F ); }
/** Override to change this creeper's explosion. */
@Override
protected void makeVariantExplosion( float explosionPower ) {
ExplosionHelper.explode( this, explosionPower, true, false );
if( level.isClientSide() ) return;
final ItemStack arrowItem = getProjectile( getItemInHand( ProjectileHelper.getWeaponHoldingHand(
this, item -> item instanceof BowItem ) ) );
final float shootPower = explosionPower * 2.0F + 4.0F;
final int count = (int) Math.ceil( shootPower * shootPower * 3.5F );
for( int i = 0; i < count; i++ ) {
AbstractArrowEntity arrow = ProjectileHelper.getMobArrow( this, arrowItem, explosionPower );
arrow.setBaseDamage( arrow.getBaseDamage() + 3.0 );
if( getMainHandItem().getItem() instanceof BowItem )
arrow = ((BowItem) getMainHandItem().getItem()).customArrow( arrow );
final float speed = (shootPower * 0.7F + random.nextFloat() * shootPower) / 20.0F;
final float pitch = random.nextFloat() * (float) Math.PI;
final float yaw = random.nextFloat() * 2.0F * (float) Math.PI;
final Vector3d velocity = new Vector3d(
MathHelper.cos( yaw ) * speed,
MathHelper.sin( pitch ) * (shootPower + random.nextFloat() * shootPower) / 18.0F,
MathHelper.sin( yaw ) * speed );
arrow.shoot( velocity.x, velocity.y, velocity.z, (float) velocity.length(), 0.0F );
level.addFreshEntity( arrow );
}
spawnAnim();
playSound( SoundEvents.SKELETON_DEATH, 1.0F, 1.0F / (random.nextFloat() * 0.4F + 0.8F) );
}
/** @return This entity's creature type. */
@Override
public CreatureAttribute getMobType() { return CreatureAttribute.UNDEAD; }
/** Called each tick to update this entity's movement. */
@Override
public void aiStep() {
if( isSunBurnTick() ) {
final ItemStack hat = getItemBySlot( EquipmentSlotType.HEAD );
if( !hat.isEmpty() ) {
if( hat.isDamageableItem() ) {
hat.setDamageValue( hat.getDamageValue() + random.nextInt( 2 ) );
if( hat.getDamageValue() >= hat.getMaxDamage() ) {
broadcastBreakEvent( EquipmentSlotType.HEAD );
setItemSlot( EquipmentSlotType.HEAD, ItemStack.EMPTY );
}
}
}
else {
setSecondsOnFire( 8 );
}
}
super.aiStep();
}
private static final ResourceLocation[] TEXTURES = {
GET_TEXTURE_PATH( "skeleton" )
};
/** @return All default textures for this entity. */
@Override
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
}