From edc83eb7bf38e82479fee54096d235b63b40e2bb Mon Sep 17 00:00:00 2001 From: FatherToast Date: Tue, 28 Jun 2022 17:29:02 -0500 Subject: [PATCH] WIP skeleton creeper --- .../common/bestiary/MobFamily.java | 2 +- .../entity/creeper/GravelCreeperEntity.java | 3 + .../entity/creeper/SkeletonCreeperEntity.java | 150 ++++++++++++++++++ .../creeper/{Skeleton.png => skeleton.png} | Bin .../creeper/{Skeleton.png => skeleton.png} | Bin 5 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 src/main/java/fathertoast/specialmobs/common/entity/creeper/SkeletonCreeperEntity.java rename src/main/resources/assets/specialmobs/textures/entity/creeper/{Skeleton.png => skeleton.png} (100%) rename src/main/resources/assets/specialmobs/textures/entityNEW/creeper/{Skeleton.png => skeleton.png} (100%) diff --git a/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java b/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java index 97d11d6..ed13090 100644 --- a/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java +++ b/src/main/java/fathertoast/specialmobs/common/bestiary/MobFamily.java @@ -40,7 +40,7 @@ public class MobFamily { public static final MobFamily 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 ZOMBIE = new MobFamily<>( diff --git a/src/main/java/fathertoast/specialmobs/common/entity/creeper/GravelCreeperEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/creeper/GravelCreeperEntity.java index 282c9fc..8cea7b6 100644 --- a/src/main/java/fathertoast/specialmobs/common/entity/creeper/GravelCreeperEntity.java +++ b/src/main/java/fathertoast/specialmobs/common/entity/creeper/GravelCreeperEntity.java @@ -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. */ diff --git a/src/main/java/fathertoast/specialmobs/common/entity/creeper/SkeletonCreeperEntity.java b/src/main/java/fathertoast/specialmobs/common/entity/creeper/SkeletonCreeperEntity.java new file mode 100644 index 0000000..f493f16 --- /dev/null +++ b/src/main/java/fathertoast/specialmobs/common/entity/creeper/SkeletonCreeperEntity.java @@ -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 SPECIES; + + @SpecialMob.BestiaryInfoSupplier + public static BestiaryInfo bestiaryInfo( EntityType.Builder 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 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; } +} \ No newline at end of file diff --git a/src/main/resources/assets/specialmobs/textures/entity/creeper/Skeleton.png b/src/main/resources/assets/specialmobs/textures/entity/creeper/skeleton.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entity/creeper/Skeleton.png rename to src/main/resources/assets/specialmobs/textures/entity/creeper/skeleton.png diff --git a/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/Skeleton.png b/src/main/resources/assets/specialmobs/textures/entityNEW/creeper/skeleton.png similarity index 100% rename from src/main/resources/assets/specialmobs/textures/entityNEW/creeper/Skeleton.png rename to src/main/resources/assets/specialmobs/textures/entityNEW/creeper/skeleton.png