mirror of
https://github.com/FatherToast/SpecialMobs.git
synced 2025-04-25 14:55:03 +00:00
Zombies
This commit is contained in:
parent
6176f4aa42
commit
5bf6e82a87
18 changed files with 773 additions and 65 deletions
|
@ -45,7 +45,7 @@ public class MobFamily<T extends LivingEntity> {
|
||||||
|
|
||||||
public static final MobFamily<ZombieEntity> ZOMBIE = new MobFamily<>(
|
public static final MobFamily<ZombieEntity> ZOMBIE = new MobFamily<>(
|
||||||
"Zombie", "zombies", 0x00AFAF, new EntityType[] { EntityType.ZOMBIE, EntityType.HUSK },
|
"Zombie", "zombies", 0x00AFAF, new EntityType[] { EntityType.ZOMBIE, EntityType.HUSK },
|
||||||
/*"Brute", "Fire", "Fishing", "Giant", "Hungry", "Husk",*/ "MadScientist"//, "Plague"
|
"Brute", "Fire", /*"Fishing",*/ "Giant", "Hungry", "Husk", "MadScientist", "Plague"
|
||||||
);
|
);
|
||||||
// public static final MobFamily<ZombieEntity> ZOMBIFIED_PIGLIN = new MobFamily<>(
|
// public static final MobFamily<ZombieEntity> ZOMBIFIED_PIGLIN = new MobFamily<>(
|
||||||
// "ZombifiedPiglin", "zombie pigmen", 0xEA9393, new EntityType[] { EntityType.ZOMBIFIED_PIGLIN },
|
// "ZombifiedPiglin", "zombie pigmen", 0xEA9393, new EntityType[] { EntityType.ZOMBIFIED_PIGLIN },
|
||||||
|
|
|
@ -32,17 +32,21 @@ public class SpecialMobs {
|
||||||
* o entity replacer
|
* o entity replacer
|
||||||
* o dimension-sensitive configs
|
* o dimension-sensitive configs
|
||||||
* o environment-sensitive configs
|
* o environment-sensitive configs
|
||||||
|
* ? natural spawning
|
||||||
* o entities
|
* o entities
|
||||||
* - nbt-driven capabilities (special mob data)
|
* - nbt-driven capabilities (special mob data)
|
||||||
|
* o fish hook
|
||||||
|
* o bug projectile
|
||||||
* + bestiary
|
* + bestiary
|
||||||
* ? configurable stats
|
* ? configurable stats
|
||||||
* - monster families (see doc for specifics)
|
* - monster families (see doc for specifics)
|
||||||
* - creepers
|
* - creepers
|
||||||
* - chance to spawn charged during thunderstorms
|
* - chance to spawn charged during thunderstorms
|
||||||
* + scope
|
* + scope
|
||||||
* o zombies
|
* - zombies
|
||||||
* o villager infection
|
* o villager infection
|
||||||
* o ranged attack AI (using bow)
|
* + transformations
|
||||||
|
* - ranged attack AI (using bow)
|
||||||
* - use shields
|
* - use shields
|
||||||
* + drowned
|
* + drowned
|
||||||
* o zombified piglins
|
* o zombified piglins
|
||||||
|
@ -51,7 +55,7 @@ public class SpecialMobs {
|
||||||
* - skeletons
|
* - skeletons
|
||||||
* - use shields
|
* - use shields
|
||||||
* - babies
|
* - babies
|
||||||
* o wither skeletons
|
* - wither skeletons
|
||||||
* - use shields
|
* - use shields
|
||||||
* - babies
|
* - babies
|
||||||
* o slimes
|
* o slimes
|
||||||
|
@ -87,8 +91,6 @@ public class SpecialMobs {
|
||||||
|
|
||||||
/** The path to the textures folder. */
|
/** The path to the textures folder. */
|
||||||
public static final String TEXTURE_PATH = "textures/entity/";
|
public static final String TEXTURE_PATH = "textures/entity/";
|
||||||
/** The path to the loot tables folder. */
|
|
||||||
public static final String LOOT_TABLE_PATH = MOD_ID + ":entities/";
|
|
||||||
|
|
||||||
/** Logger instance for the mod. */
|
/** Logger instance for the mod. */
|
||||||
public static final Logger LOG = LogManager.getLogger( MOD_ID );
|
public static final Logger LOG = LogManager.getLogger( MOD_ID );
|
||||||
|
|
|
@ -176,8 +176,8 @@ public final class MobHelper {
|
||||||
public static EffectInstance nextPlagueEffect( Random random, World world ) {
|
public static EffectInstance nextPlagueEffect( Random random, World world ) {
|
||||||
final int duration = MobHelper.getDebuffDuration( world.getDifficulty() );
|
final int duration = MobHelper.getDebuffDuration( world.getDifficulty() );
|
||||||
|
|
||||||
//EffectInstance potion = POTIONS_PLAGUE[random.nextInt( POTIONS_PLAGUE.length - (Config.get().GENERAL.DISABLE_NAUSEA ? 1 : 0) )]; TODO config
|
//final EffectInstance potion = PLAGUE_EFFECTS[random.nextInt( PLAGUE_EFFECTS.length - (Config.get().GENERAL.DISABLE_NAUSEA ? 1 : 0) )]; TODO config
|
||||||
EffectInstance potion = PLAGUE_EFFECTS[random.nextInt( PLAGUE_EFFECTS.length )];
|
final EffectInstance potion = PLAGUE_EFFECTS[random.nextInt( PLAGUE_EFFECTS.length )];
|
||||||
return new EffectInstance( potion.getEffect(), duration * potion.getDuration(), potion.getAmplifier() );
|
return new EffectInstance( potion.getEffect(), duration * potion.getDuration(), potion.getAmplifier() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ public final class MobHelper {
|
||||||
public static EffectInstance nextWitchSpiderEffect( Random random, World world, boolean includePoison ) {
|
public static EffectInstance nextWitchSpiderEffect( Random random, World world, boolean includePoison ) {
|
||||||
final int duration = MobHelper.getDebuffDuration( world.getDifficulty() );
|
final int duration = MobHelper.getDebuffDuration( world.getDifficulty() );
|
||||||
|
|
||||||
EffectInstance potion = WITCH_EFFECTS[random.nextInt( WITCH_EFFECTS.length - (includePoison ? 0 : 1) )];
|
final EffectInstance potion = WITCH_EFFECTS[random.nextInt( WITCH_EFFECTS.length - (includePoison ? 0 : 1) )];
|
||||||
return new EffectInstance( potion.getEffect(), duration * potion.getDuration(), potion.getAmplifier() );
|
return new EffectInstance( potion.getEffect(), duration * potion.getDuration(), potion.getAmplifier() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class _SpecialCaveSpiderEntity extends CaveSpiderEntity implements ISpeci
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialCaveSpiderEntity( EntityType<? extends _SpecialCaveSpiderEntity> entityType, World world ) {
|
public _SpecialCaveSpiderEntity( EntityType<? extends _SpecialCaveSpiderEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ public class _SpecialCaveSpiderEntity extends CaveSpiderEntity implements ISpeci
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -186,7 +186,7 @@ public class _SpecialCaveSpiderEntity extends CaveSpiderEntity implements ISpeci
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class _SpecialCreeperEntity extends CreeperEntity implements ISpecialMob<
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialCreeperEntity( EntityType<? extends _SpecialCreeperEntity> entityType, World world ) {
|
public _SpecialCreeperEntity( EntityType<? extends _SpecialCreeperEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ public class _SpecialCreeperEntity extends CreeperEntity implements ISpecialMob<
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -316,7 +316,7 @@ public class _SpecialCreeperEntity extends CreeperEntity implements ISpecialMob<
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class _SpecialEndermanEntity extends EndermanEntity implements ISpecialMo
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialEndermanEntity( EntityType<? extends _SpecialEndermanEntity> entityType, World world ) {
|
public _SpecialEndermanEntity( EntityType<? extends _SpecialEndermanEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
getSpecialData().setDamagedByWater( true );
|
getSpecialData().setDamagedByWater( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ public class _SpecialEndermanEntity extends EndermanEntity implements ISpecialMo
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -179,7 +179,7 @@ public class _SpecialEndermanEntity extends EndermanEntity implements ISpecialMo
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class _SpecialSilverfishEntity extends SilverfishEntity implements ISpeci
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialSilverfishEntity( EntityType<? extends _SpecialSilverfishEntity> entityType, World world ) {
|
public _SpecialSilverfishEntity( EntityType<? extends _SpecialSilverfishEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,7 +191,7 @@ public class _SpecialSilverfishEntity extends SilverfishEntity implements ISpeci
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -206,7 +206,7 @@ public class _SpecialSilverfishEntity extends SilverfishEntity implements ISpeci
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class _SpecialSkeletonEntity extends AbstractSkeletonEntity implements IS
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialSkeletonEntity( EntityType<? extends _SpecialSkeletonEntity> entityType, World world ) {
|
public _SpecialSkeletonEntity( EntityType<? extends _SpecialSkeletonEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ public class _SpecialSkeletonEntity extends AbstractSkeletonEntity implements IS
|
||||||
return groupData;
|
return groupData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called to change */
|
/** Called to set this entity's attack AI based on current equipment. */
|
||||||
@Override
|
@Override
|
||||||
public void reassessWeaponGoal() {
|
public void reassessWeaponGoal() {
|
||||||
if( level != null && !level.isClientSide ) {
|
if( level != null && !level.isClientSide ) {
|
||||||
|
@ -358,7 +358,7 @@ public class _SpecialSkeletonEntity extends AbstractSkeletonEntity implements IS
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -373,7 +373,7 @@ public class _SpecialSkeletonEntity extends AbstractSkeletonEntity implements IS
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class _SpecialSpiderEntity extends SpiderEntity implements ISpecialMob<_S
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialSpiderEntity( EntityType<? extends _SpecialSpiderEntity> entityType, World world ) {
|
public _SpecialSpiderEntity( EntityType<? extends _SpecialSpiderEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -171,7 +171,7 @@ public class _SpecialSpiderEntity extends SpiderEntity implements ISpecialMob<_S
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -186,7 +186,7 @@ public class _SpecialSpiderEntity extends SpiderEntity implements ISpecialMob<_S
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class _SpecialWitherSkeletonEntity extends WitherSkeletonEntity implement
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialWitherSkeletonEntity( EntityType<? extends _SpecialWitherSkeletonEntity> entityType, World world ) {
|
public _SpecialWitherSkeletonEntity( EntityType<? extends _SpecialWitherSkeletonEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
getSpecialData().initialize();
|
||||||
getSpecialData().setImmuneToFire( true );
|
getSpecialData().setImmuneToFire( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,7 +207,7 @@ public class _SpecialWitherSkeletonEntity extends WitherSkeletonEntity implement
|
||||||
return groupData;
|
return groupData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called to change */
|
/** Called to set this entity's attack AI based on current equipment. */
|
||||||
@Override
|
@Override
|
||||||
public void reassessWeaponGoal() {
|
public void reassessWeaponGoal() {
|
||||||
if( level != null && !level.isClientSide ) {
|
if( level != null && !level.isClientSide ) {
|
||||||
|
@ -321,7 +321,7 @@ public class _SpecialWitherSkeletonEntity extends WitherSkeletonEntity implement
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -336,7 +336,7 @@ public class _SpecialWitherSkeletonEntity extends WitherSkeletonEntity implement
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
package fathertoast.specialmobs.common.entity.zombie;
|
||||||
|
|
||||||
|
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
|
||||||
|
import fathertoast.specialmobs.common.bestiary.SpecialMob;
|
||||||
|
import fathertoast.specialmobs.common.entity.MobHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.AttributeHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.References;
|
||||||
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
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.projectile.AbstractArrowEntity;
|
||||||
|
import net.minecraft.entity.projectile.ArrowEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.potion.EffectInstance;
|
||||||
|
import net.minecraft.potion.Effects;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@SpecialMob
|
||||||
|
public class BruteZombieEntity extends _SpecialZombieEntity {
|
||||||
|
|
||||||
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
|
entityType.sized( 0.7F, 2.35F );
|
||||||
|
return new BestiaryInfo( 0xFFF87E );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.AttributeCreator
|
||||||
|
public static AttributeModifierMap.MutableAttribute createAttributes() {
|
||||||
|
return AttributeHelper.of( _SpecialZombieEntity.createAttributes() )
|
||||||
|
.addAttribute( Attributes.MAX_HEALTH, 10.0 )
|
||||||
|
.addAttribute( Attributes.ARMOR, 10.0 )
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LanguageProvider
|
||||||
|
public static String[] getTranslations( String langKey ) {
|
||||||
|
return References.translations( langKey, "Zombie Brute",
|
||||||
|
"", "", "", "", "", "" );//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LootTableProvider
|
||||||
|
public static void buildLootTable( LootTableBuilder loot ) {
|
||||||
|
addBaseLoot( loot );
|
||||||
|
loot.addCommonDrop( "common", Items.FLINT, 1 );
|
||||||
|
loot.addRareDrop( "rare", Items.IRON_INGOT );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.Constructor
|
||||||
|
public BruteZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
|
super( entityType, world );
|
||||||
|
getSpecialData().setBaseScale( 1.2F );
|
||||||
|
xpReward += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Variant-Specific Implementations ----------------
|
||||||
|
|
||||||
|
/** Override to apply effects when this entity hits a target with a melee attack. */
|
||||||
|
@Override
|
||||||
|
protected void onVariantAttack( Entity target ) {
|
||||||
|
if( target instanceof LivingEntity ) {
|
||||||
|
MobHelper.causeLifeLoss( (LivingEntity) target, 2.0F );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to modify this entity's ranged attack projectile. */
|
||||||
|
@Override
|
||||||
|
protected AbstractArrowEntity getVariantArrow( AbstractArrowEntity arrow, ItemStack arrowItem, float damageMulti ) {
|
||||||
|
if( arrow instanceof ArrowEntity ) {
|
||||||
|
((ArrowEntity) arrow).addEffect( new EffectInstance( Effects.HARM, 1 ) );
|
||||||
|
}
|
||||||
|
return arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = {
|
||||||
|
GET_TEXTURE_PATH( "brute" ),
|
||||||
|
null,
|
||||||
|
GET_TEXTURE_PATH( "brute_overlay" )
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @return All default textures for this entity. */
|
||||||
|
@Override
|
||||||
|
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
|
||||||
|
}
|
|
@ -0,0 +1,102 @@
|
||||||
|
package fathertoast.specialmobs.common.entity.zombie;
|
||||||
|
|
||||||
|
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.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
||||||
|
import net.minecraft.entity.projectile.AbstractArrowEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.SoundEvent;
|
||||||
|
import net.minecraft.util.SoundEvents;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@SpecialMob
|
||||||
|
public class FireZombieEntity extends _SpecialZombieEntity {
|
||||||
|
|
||||||
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
|
entityType.fireImmune();
|
||||||
|
return new BestiaryInfo( 0xDC1A00 );
|
||||||
|
//TODO theme - fire
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.AttributeCreator
|
||||||
|
public static AttributeModifierMap.MutableAttribute createAttributes() {
|
||||||
|
return _SpecialZombieEntity.createAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LanguageProvider
|
||||||
|
public static String[] getTranslations( String langKey ) {
|
||||||
|
return References.translations( langKey, "Fire Zombie",
|
||||||
|
"", "", "", "", "", "" );//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LootTableProvider
|
||||||
|
public static void buildLootTable( LootTableBuilder loot ) {
|
||||||
|
addBaseLoot( loot );
|
||||||
|
loot.addCommonDrop( "common", Items.FIRE_CHARGE );
|
||||||
|
loot.addUncommonDrop( "uncommon", Items.COAL );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.Constructor
|
||||||
|
public FireZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
|
super( entityType, world );
|
||||||
|
getSpecialData().setImmuneToFire( true );
|
||||||
|
getSpecialData().setDamagedByWater( true );
|
||||||
|
xpReward += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Variant-Specific Implementations ----------------
|
||||||
|
|
||||||
|
/** Override to apply effects when this entity hits a target with a melee attack. */
|
||||||
|
@Override
|
||||||
|
protected void onVariantAttack( Entity target ) {
|
||||||
|
target.setSecondsOnFire( 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to modify this entity's ranged attack projectile. */
|
||||||
|
@Override
|
||||||
|
protected AbstractArrowEntity getVariantArrow( AbstractArrowEntity arrow, ItemStack arrowItem, float damageMulti ) {
|
||||||
|
arrow.setSecondsOnFire( 100 );
|
||||||
|
return arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return The sound this entity makes idly. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getAmbientSound() { return SoundEvents.HUSK_AMBIENT; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes when damaged. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getHurtSound( DamageSource source ) { return SoundEvents.HUSK_HURT; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes when killed. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getDeathSound() { return SoundEvents.HUSK_DEATH; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes while walking. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getStepSound() { return SoundEvents.HUSK_STEP; }
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = {
|
||||||
|
GET_TEXTURE_PATH( "fire" )
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @return All default textures for this entity. */
|
||||||
|
@Override
|
||||||
|
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
package fathertoast.specialmobs.common.entity.zombie;
|
||||||
|
|
||||||
|
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
|
||||||
|
import fathertoast.specialmobs.common.bestiary.SpecialMob;
|
||||||
|
import fathertoast.specialmobs.common.util.AttributeHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.References;
|
||||||
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
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.item.Items;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@SpecialMob
|
||||||
|
public class GiantZombieEntity extends _SpecialZombieEntity {
|
||||||
|
|
||||||
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
|
entityType.sized( 0.9F, 2.95F );
|
||||||
|
return new BestiaryInfo( 0x799C65 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.AttributeCreator
|
||||||
|
public static AttributeModifierMap.MutableAttribute createAttributes() {
|
||||||
|
return AttributeHelper.of( _SpecialZombieEntity.createAttributes() )
|
||||||
|
.addAttribute( Attributes.MAX_HEALTH, 20.0 )
|
||||||
|
.addAttribute( Attributes.ATTACK_DAMAGE, 2.0 )
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LanguageProvider
|
||||||
|
public static String[] getTranslations( String langKey ) {
|
||||||
|
return References.translations( langKey, "Giant Zombie",
|
||||||
|
"", "", "", "", "", "" );//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LootTableProvider
|
||||||
|
public static void buildLootTable( LootTableBuilder loot ) {
|
||||||
|
addBaseLoot( loot );
|
||||||
|
loot.addGuaranteedDrop( "base", Items.ROTTEN_FLESH, 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.Constructor
|
||||||
|
public GiantZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
|
super( entityType, world );
|
||||||
|
getSpecialData().setBaseScale( 1.5F );
|
||||||
|
maxUpStep = 1.0F;
|
||||||
|
xpReward += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Variant-Specific Implementations ----------------
|
||||||
|
|
||||||
|
/** Override to change this entity's AI goals. */
|
||||||
|
@Override
|
||||||
|
protected void registerVariantGoals() {
|
||||||
|
getSpecialData().rangedAttackDamage += 2.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Sets this entity as a baby. */
|
||||||
|
@Override
|
||||||
|
public void setBaby( boolean value ) { }
|
||||||
|
|
||||||
|
/** @return True if this entity is a baby. */
|
||||||
|
@Override
|
||||||
|
public boolean isBaby() { return false; }
|
||||||
|
}
|
|
@ -0,0 +1,114 @@
|
||||||
|
package fathertoast.specialmobs.common.entity.zombie;
|
||||||
|
|
||||||
|
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
|
||||||
|
import fathertoast.specialmobs.common.bestiary.SpecialMob;
|
||||||
|
import fathertoast.specialmobs.common.entity.MobHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.AttributeHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.References;
|
||||||
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
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.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Food;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.SoundEvents;
|
||||||
|
import net.minecraft.world.DifficultyInstance;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.event.ForgeEventFactory;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@SpecialMob
|
||||||
|
public class HungryZombieEntity extends _SpecialZombieEntity {
|
||||||
|
|
||||||
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
|
return new BestiaryInfo( 0xAB1518 );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.AttributeCreator
|
||||||
|
public static AttributeModifierMap.MutableAttribute createAttributes() {
|
||||||
|
return AttributeHelper.of( _SpecialZombieEntity.createAttributes() )
|
||||||
|
.addAttribute( Attributes.MAX_HEALTH, 10.0 )
|
||||||
|
.multAttribute( Attributes.MOVEMENT_SPEED, 1.3 )
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LanguageProvider
|
||||||
|
public static String[] getTranslations( String langKey ) {
|
||||||
|
return References.translations( langKey, "Hungry Zombie",
|
||||||
|
"", "", "", "", "", "" );//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LootTableProvider
|
||||||
|
public static void buildLootTable( LootTableBuilder loot ) {
|
||||||
|
addBaseLoot( loot );
|
||||||
|
loot.addCommonDrop( "common", Items.BONE );
|
||||||
|
loot.addUncommonDrop( "uncommon", Items.BEEF, Items.CHICKEN, Items.MUTTON, Items.PORKCHOP, Items.RABBIT, Items.COOKIE );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.Constructor
|
||||||
|
public HungryZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
|
super( entityType, world );
|
||||||
|
getSpecialData().setRegenerationTime( 30 );
|
||||||
|
xpReward += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Variant-Specific Implementations ----------------
|
||||||
|
|
||||||
|
/** Override to change this entity's AI goals. */
|
||||||
|
@Override
|
||||||
|
protected void registerVariantGoals() {
|
||||||
|
disableRangedAI();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called during spawn finalization to set starting equipment. */
|
||||||
|
@Override
|
||||||
|
protected void populateDefaultEquipmentSlots( DifficultyInstance difficulty ) {
|
||||||
|
super.populateDefaultEquipmentSlots( difficulty );
|
||||||
|
setCanPickUpLoot( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to change this entity's chance to spawn with a bow. */
|
||||||
|
@Override
|
||||||
|
protected double getVariantBowChance() { return 0.0; }
|
||||||
|
|
||||||
|
/** Override to apply effects when this entity hits a target with a melee attack. */
|
||||||
|
@Override
|
||||||
|
protected void onVariantAttack( Entity target ) {
|
||||||
|
if( level.isClientSide() ) return;
|
||||||
|
|
||||||
|
if( target instanceof PlayerEntity && ForgeEventFactory.getMobGriefingEvent( level, this ) ) {
|
||||||
|
final ItemStack food = MobHelper.stealRandomFood( (PlayerEntity) target );
|
||||||
|
if( !food.isEmpty() ) {
|
||||||
|
final Food foodStats = food.getItem().getFoodProperties();
|
||||||
|
heal( Math.max( foodStats == null ? 0.0F : foodStats.getNutrition(), 1.0F ) );
|
||||||
|
playSound( SoundEvents.PLAYER_BURP, 0.5F, random.nextFloat() * 0.1F + 0.9F );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Take a bite out of the target if they have no food to eat
|
||||||
|
if( target instanceof LivingEntity ) {
|
||||||
|
MobHelper.stealLife( this, (LivingEntity) target, 2.0F );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = {
|
||||||
|
GET_TEXTURE_PATH( "hungry" )
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @return All default textures for this entity. */
|
||||||
|
@Override
|
||||||
|
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
package fathertoast.specialmobs.common.entity.zombie;
|
||||||
|
|
||||||
|
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
|
||||||
|
import fathertoast.specialmobs.common.bestiary.SpecialMob;
|
||||||
|
import fathertoast.specialmobs.common.entity.MobHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.References;
|
||||||
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
||||||
|
import net.minecraft.entity.projectile.AbstractArrowEntity;
|
||||||
|
import net.minecraft.entity.projectile.ArrowEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.potion.EffectInstance;
|
||||||
|
import net.minecraft.potion.Effects;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.SoundEvent;
|
||||||
|
import net.minecraft.util.SoundEvents;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@SpecialMob
|
||||||
|
public class HuskZombieEntity extends _SpecialZombieEntity {
|
||||||
|
|
||||||
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
|
return new BestiaryInfo( 0xE6CC94, BestiaryInfo.BaseWeight.LOW );
|
||||||
|
//TODO theme - desert
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.AttributeCreator
|
||||||
|
public static AttributeModifierMap.MutableAttribute createAttributes() {
|
||||||
|
return _SpecialZombieEntity.createAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LanguageProvider
|
||||||
|
public static String[] getTranslations( String langKey ) {
|
||||||
|
return References.translations( langKey, "Husk",
|
||||||
|
"", "", "", "", "", "" );//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LootTableProvider
|
||||||
|
public static void buildLootTable( LootTableBuilder loot ) {
|
||||||
|
loot.addLootTable( "main", EntityType.HUSK.getDefaultLootTable() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.Constructor
|
||||||
|
public HuskZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
|
super( entityType, world );
|
||||||
|
getSpecialData().setBaseScale( 1.0625F );
|
||||||
|
xpReward += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Variant-Specific Implementations ----------------
|
||||||
|
|
||||||
|
/** Override to apply effects when this entity hits a target with a melee attack. */
|
||||||
|
@Override
|
||||||
|
protected void onVariantAttack( Entity target ) {
|
||||||
|
if( target instanceof LivingEntity ) {
|
||||||
|
final LivingEntity livingTarget = (LivingEntity) target;
|
||||||
|
final int duration = MobHelper.getDebuffDuration( level.getDifficulty() );
|
||||||
|
|
||||||
|
livingTarget.addEffect( new EffectInstance( Effects.HUNGER, duration ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to modify this entity's ranged attack projectile. */
|
||||||
|
@Override
|
||||||
|
protected AbstractArrowEntity getVariantArrow( AbstractArrowEntity arrow, ItemStack arrowItem, float damageMulti ) {
|
||||||
|
if( arrow instanceof ArrowEntity ) {
|
||||||
|
final int duration = MobHelper.getDebuffDuration( level.getDifficulty() );
|
||||||
|
|
||||||
|
((ArrowEntity) arrow).addEffect( new EffectInstance( Effects.HUNGER, duration ) );
|
||||||
|
}
|
||||||
|
return arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = {
|
||||||
|
new ResourceLocation( "textures/entity/zombie/husk.png" )
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @return All default textures for this entity. */
|
||||||
|
@Override
|
||||||
|
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Husk Implementations ----------------
|
||||||
|
|
||||||
|
/** @return True if this zombie burns in sunlight. */
|
||||||
|
@Override
|
||||||
|
protected boolean isSunSensitive() { return false; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes idly. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getAmbientSound() { return SoundEvents.HUSK_AMBIENT; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes when damaged. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getHurtSound( DamageSource source ) { return SoundEvents.HUSK_HURT; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes when killed. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getDeathSound() { return SoundEvents.HUSK_DEATH; }
|
||||||
|
|
||||||
|
/** @return The sound this entity makes while walking. */
|
||||||
|
@Override
|
||||||
|
protected SoundEvent getStepSound() { return SoundEvents.HUSK_STEP; }
|
||||||
|
}
|
|
@ -10,20 +10,19 @@ import fathertoast.specialmobs.common.util.AttributeHelper;
|
||||||
import fathertoast.specialmobs.common.util.References;
|
import fathertoast.specialmobs.common.util.References;
|
||||||
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
import mcp.MethodsReturnNonnullByDefault;
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
import net.minecraft.entity.*;
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
||||||
import net.minecraft.entity.ai.attributes.Attributes;
|
import net.minecraft.entity.ai.attributes.Attributes;
|
||||||
import net.minecraft.inventory.EquipmentSlotType;
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
|
||||||
import net.minecraft.potion.EffectInstance;
|
import net.minecraft.potion.EffectInstance;
|
||||||
import net.minecraft.potion.Effects;
|
import net.minecraft.potion.Effects;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
import net.minecraft.world.DifficultyInstance;
|
import net.minecraft.world.DifficultyInstance;
|
||||||
import net.minecraft.world.IServerWorld;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
|
@ -70,11 +69,30 @@ public class MadScientistZombieEntity extends _SpecialZombieEntity {
|
||||||
/** Override to change this entity's AI goals. */
|
/** Override to change this entity's AI goals. */
|
||||||
@Override
|
@Override
|
||||||
protected void registerVariantGoals() {
|
protected void registerVariantGoals() {
|
||||||
|
disableRangedAI();
|
||||||
|
|
||||||
AIHelper.insertGoal( goalSelector, 2, new SpecialInjectCreeperGoal<>(
|
AIHelper.insertGoal( goalSelector, 2, new SpecialInjectCreeperGoal<>(
|
||||||
this, 1.0D, 20.0D,
|
this, 1.0D, 20.0D,
|
||||||
( madman, creeper ) -> creeper.isAlive() && !creeper.isPowered() && madman.getSensing().canSee( creeper ) ) );
|
( madman, creeper ) -> creeper.isAlive() && !creeper.isPowered() && madman.getSensing().canSee( creeper ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Override to change this entity's attack goal priority. */
|
||||||
|
@Override
|
||||||
|
protected int getVariantAttackPriority() { return super.getVariantAttackPriority() + 1; }
|
||||||
|
|
||||||
|
/** Called during spawn finalization to set starting equipment. */
|
||||||
|
@Override
|
||||||
|
protected void populateDefaultEquipmentSlots( DifficultyInstance difficulty ) {
|
||||||
|
super.populateDefaultEquipmentSlots( difficulty );
|
||||||
|
|
||||||
|
setItemSlot( EquipmentSlotType.MAINHAND, new ItemStack( SMItems.SYRINGE.get() ) );
|
||||||
|
setDropChance( EquipmentSlotType.MAINHAND, 0.0F );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to change this entity's chance to spawn with a bow. */
|
||||||
|
@Override
|
||||||
|
protected double getVariantBowChance() { return 0.0; }
|
||||||
|
|
||||||
/** Override to apply effects when this entity hits a target with a melee attack. */
|
/** Override to apply effects when this entity hits a target with a melee attack. */
|
||||||
@Override
|
@Override
|
||||||
protected void onVariantAttack( Entity target ) {
|
protected void onVariantAttack( Entity target ) {
|
||||||
|
@ -86,27 +104,6 @@ public class MadScientistZombieEntity extends _SpecialZombieEntity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called on spawn to initialize properties based on the world, difficulty, and the group it spawns with. */
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public ILivingEntityData finalizeSpawn( IServerWorld world, DifficultyInstance difficulty, SpawnReason spawnReason,
|
|
||||||
@Nullable ILivingEntityData groupData, @Nullable CompoundNBT eggTag ) {
|
|
||||||
this.populateDefaultEquipmentSlots( difficulty );
|
|
||||||
return super.finalizeSpawn( world, difficulty, spawnReason, groupData, eggTag );
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Only drop armor. The syringe item should be dropped from the loot table, and not from the hand item. **/
|
|
||||||
@Override
|
|
||||||
protected float getEquipmentDropChance( EquipmentSlotType slotType ) {
|
|
||||||
return slotType.getType() == EquipmentSlotType.Group.ARMOR ? this.armorDropChances[slotType.getIndex()] : 0.0F;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void populateDefaultEquipmentSlots( DifficultyInstance difficultyInstance ) {
|
|
||||||
super.populateDefaultEquipmentSlots( difficultyInstance );
|
|
||||||
this.setItemSlot( EquipmentSlotType.MAINHAND, new ItemStack( SMItems.SYRINGE.get() ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final ResourceLocation[] TEXTURES = {
|
private static final ResourceLocation[] TEXTURES = {
|
||||||
GET_TEXTURE_PATH( "madscientist" ),
|
GET_TEXTURE_PATH( "madscientist" ),
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
package fathertoast.specialmobs.common.entity.zombie;
|
||||||
|
|
||||||
|
import fathertoast.specialmobs.common.bestiary.BestiaryInfo;
|
||||||
|
import fathertoast.specialmobs.common.bestiary.SpecialMob;
|
||||||
|
import fathertoast.specialmobs.common.entity.MobHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.AttributeHelper;
|
||||||
|
import fathertoast.specialmobs.common.util.References;
|
||||||
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
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.projectile.AbstractArrowEntity;
|
||||||
|
import net.minecraft.entity.projectile.ArrowEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.potion.EffectInstance;
|
||||||
|
import net.minecraft.potion.Effects;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
@MethodsReturnNonnullByDefault
|
||||||
|
@SpecialMob
|
||||||
|
public class PlagueZombieEntity extends _SpecialZombieEntity {
|
||||||
|
|
||||||
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
|
return new BestiaryInfo( 0x8AA838 );
|
||||||
|
//TODO theme - forest
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.AttributeCreator
|
||||||
|
public static AttributeModifierMap.MutableAttribute createAttributes() {
|
||||||
|
return AttributeHelper.of( _SpecialZombieEntity.createAttributes() )
|
||||||
|
.multAttribute( Attributes.MOVEMENT_SPEED, 1.1 )
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LanguageProvider
|
||||||
|
public static String[] getTranslations( String langKey ) {
|
||||||
|
return References.translations( langKey, "Plague Zombie",
|
||||||
|
"", "", "", "", "", "" );//TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.LootTableProvider
|
||||||
|
public static void buildLootTable( LootTableBuilder loot ) {
|
||||||
|
addBaseLoot( loot );
|
||||||
|
loot.addUncommonDrop( "uncommon", Items.POISONOUS_POTATO, Items.SPIDER_EYE, Items.FERMENTED_SPIDER_EYE,
|
||||||
|
Blocks.RED_MUSHROOM, Blocks.BROWN_MUSHROOM );
|
||||||
|
}
|
||||||
|
|
||||||
|
@SpecialMob.Constructor
|
||||||
|
public PlagueZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
|
super( entityType, world );
|
||||||
|
xpReward += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------- Variant-Specific Implementations ----------------
|
||||||
|
|
||||||
|
/** Override to apply effects when this entity hits a target with a melee attack. */
|
||||||
|
@Override
|
||||||
|
protected void onVariantAttack( Entity target ) {
|
||||||
|
if( target instanceof LivingEntity ) {
|
||||||
|
((LivingEntity) target).addEffect( MobHelper.nextPlagueEffect( random, level ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to modify this entity's ranged attack projectile. */
|
||||||
|
@Override
|
||||||
|
protected AbstractArrowEntity getVariantArrow( AbstractArrowEntity arrow, ItemStack arrowItem, float damageMulti ) {
|
||||||
|
if( arrow instanceof ArrowEntity ) {
|
||||||
|
((ArrowEntity) arrow).addEffect( MobHelper.nextPlagueEffect( random, level ) );
|
||||||
|
}
|
||||||
|
return arrow;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final ResourceLocation[] TEXTURES = {
|
||||||
|
GET_TEXTURE_PATH( "plague" )
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @return All default textures for this entity. */
|
||||||
|
@Override
|
||||||
|
public ResourceLocation[] getDefaultTextures() { return TEXTURES; }
|
||||||
|
}
|
|
@ -6,15 +6,25 @@ import fathertoast.specialmobs.common.core.SpecialMobs;
|
||||||
import fathertoast.specialmobs.common.entity.ISpecialMob;
|
import fathertoast.specialmobs.common.entity.ISpecialMob;
|
||||||
import fathertoast.specialmobs.common.entity.MobHelper;
|
import fathertoast.specialmobs.common.entity.MobHelper;
|
||||||
import fathertoast.specialmobs.common.entity.SpecialMobData;
|
import fathertoast.specialmobs.common.entity.SpecialMobData;
|
||||||
|
import fathertoast.specialmobs.common.entity.ai.AIHelper;
|
||||||
import fathertoast.specialmobs.common.util.References;
|
import fathertoast.specialmobs.common.util.References;
|
||||||
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
import fathertoast.specialmobs.datagen.loot.LootTableBuilder;
|
||||||
import mcp.MethodsReturnNonnullByDefault;
|
import mcp.MethodsReturnNonnullByDefault;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.*;
|
import net.minecraft.entity.*;
|
||||||
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
import net.minecraft.entity.ai.attributes.AttributeModifierMap;
|
||||||
|
import net.minecraft.entity.ai.goal.Goal;
|
||||||
|
import net.minecraft.entity.ai.goal.RangedBowAttackGoal;
|
||||||
|
import net.minecraft.entity.ai.goal.ZombieAttackGoal;
|
||||||
import net.minecraft.entity.monster.ZombieEntity;
|
import net.minecraft.entity.monster.ZombieEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.entity.projectile.AbstractArrowEntity;
|
||||||
|
import net.minecraft.entity.projectile.ProjectileHelper;
|
||||||
import net.minecraft.entity.projectile.SnowballEntity;
|
import net.minecraft.entity.projectile.SnowballEntity;
|
||||||
|
import net.minecraft.inventory.EquipmentSlotType;
|
||||||
|
import net.minecraft.item.BowItem;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.network.datasync.DataParameter;
|
import net.minecraft.network.datasync.DataParameter;
|
||||||
import net.minecraft.network.datasync.DataSerializers;
|
import net.minecraft.network.datasync.DataSerializers;
|
||||||
|
@ -22,6 +32,8 @@ import net.minecraft.network.datasync.EntityDataManager;
|
||||||
import net.minecraft.potion.EffectInstance;
|
import net.minecraft.potion.EffectInstance;
|
||||||
import net.minecraft.util.DamageSource;
|
import net.minecraft.util.DamageSource;
|
||||||
import net.minecraft.util.ResourceLocation;
|
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.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.DifficultyInstance;
|
import net.minecraft.world.DifficultyInstance;
|
||||||
import net.minecraft.world.IServerWorld;
|
import net.minecraft.world.IServerWorld;
|
||||||
|
@ -33,13 +45,13 @@ import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
@ParametersAreNonnullByDefault
|
@ParametersAreNonnullByDefault
|
||||||
@MethodsReturnNonnullByDefault
|
@MethodsReturnNonnullByDefault
|
||||||
@SpecialMob
|
@SpecialMob
|
||||||
public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_SpecialZombieEntity> {
|
public class _SpecialZombieEntity extends ZombieEntity implements IRangedAttackMob, ISpecialMob<_SpecialZombieEntity> {
|
||||||
|
|
||||||
//--------------- Static Special Mob Hooks ----------------
|
//--------------- Static Special Mob Hooks ----------------
|
||||||
|
|
||||||
@SpecialMob.BestiaryInfoSupplier
|
@SpecialMob.BestiaryInfoSupplier
|
||||||
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
public static BestiaryInfo bestiaryInfo( EntityType.Builder<LivingEntity> entityType ) {
|
||||||
return new BestiaryInfo( 0x799C65 );
|
return new BestiaryInfo( 0x799C65 );//sized(0.6F, 1.95F)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SpecialMob.AttributeCreator
|
@SpecialMob.AttributeCreator
|
||||||
|
@ -61,7 +73,8 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
@SpecialMob.Constructor
|
@SpecialMob.Constructor
|
||||||
public _SpecialZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
public _SpecialZombieEntity( EntityType<? extends _SpecialZombieEntity> entityType, World world ) {
|
||||||
super( entityType, world );
|
super( entityType, world );
|
||||||
specialData.initialize();
|
reassessWeaponGoal();
|
||||||
|
getSpecialData().initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -71,9 +84,11 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
@Override
|
@Override
|
||||||
protected void registerGoals() {
|
protected void registerGoals() {
|
||||||
super.registerGoals();
|
super.registerGoals();
|
||||||
|
AIHelper.removeGoals( goalSelector, ZombieAttackGoal.class );
|
||||||
|
|
||||||
getSpecialData().rangedAttackDamage = 2.0F;
|
getSpecialData().rangedAttackDamage = 2.0F;
|
||||||
getSpecialData().rangedAttackSpread = 18.0F;
|
getSpecialData().rangedAttackSpread = 20.0F;
|
||||||
|
getSpecialData().rangedWalkSpeed = 0.8F;
|
||||||
getSpecialData().rangedAttackCooldown = 30;
|
getSpecialData().rangedAttackCooldown = 30;
|
||||||
getSpecialData().rangedAttackMaxCooldown = getSpecialData().rangedAttackCooldown;
|
getSpecialData().rangedAttackMaxCooldown = getSpecialData().rangedAttackCooldown;
|
||||||
getSpecialData().rangedAttackMaxRange = 12.0F;
|
getSpecialData().rangedAttackMaxRange = 12.0F;
|
||||||
|
@ -83,6 +98,68 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
/** Override to change this entity's AI goals. */
|
/** Override to change this entity's AI goals. */
|
||||||
protected void registerVariantGoals() { }
|
protected void registerVariantGoals() { }
|
||||||
|
|
||||||
|
/** Helper method to set the ranged attack AI more easily. */
|
||||||
|
protected void disableRangedAI() { setRangedAI( 1.0, 20, 0.0F ); }
|
||||||
|
|
||||||
|
/** Helper method to set the ranged attack AI more easily. */
|
||||||
|
protected void setRangedAI( double walkSpeed, int cooldownTime ) {
|
||||||
|
getSpecialData().rangedWalkSpeed = (float) walkSpeed;
|
||||||
|
getSpecialData().rangedAttackCooldown = cooldownTime;
|
||||||
|
getSpecialData().rangedAttackMaxCooldown = cooldownTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Helper method to set the ranged attack AI more easily. */
|
||||||
|
protected void setRangedAI( double walkSpeed, int cooldownTime, float range ) {
|
||||||
|
setRangedAI( walkSpeed, cooldownTime );
|
||||||
|
getSpecialData().rangedAttackMaxRange = range;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to change this entity's attack goal priority. */
|
||||||
|
protected int getVariantAttackPriority() { return 2; }
|
||||||
|
|
||||||
|
/** Called during spawn finalization to set starting equipment. */
|
||||||
|
@Override
|
||||||
|
protected void populateDefaultEquipmentSlots( DifficultyInstance difficulty ) {
|
||||||
|
super.populateDefaultEquipmentSlots( difficulty );
|
||||||
|
if( random.nextDouble() < getVariantBowChance() ) { //TODO config the default 5% chance
|
||||||
|
setItemSlot( EquipmentSlotType.MAINHAND, new ItemStack( Items.BOW ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to change this entity's chance to spawn with a bow. */
|
||||||
|
protected double getVariantBowChance() { return getSpecialData().rangedAttackMaxRange > 0.0F ? 0.05 : 0.0; }
|
||||||
|
|
||||||
|
/** Called to attack the target with a ranged attack. */
|
||||||
|
@Override
|
||||||
|
public void performRangedAttack( LivingEntity target, float damageMulti ) {
|
||||||
|
final ItemStack arrowItem = getProjectile( getItemInHand( ProjectileHelper.getWeaponHoldingHand(
|
||||||
|
this, item -> item instanceof BowItem ) ) );
|
||||||
|
AbstractArrowEntity arrow = getArrow( arrowItem, damageMulti );
|
||||||
|
if( getMainHandItem().getItem() instanceof BowItem )
|
||||||
|
arrow = ((BowItem) getMainHandItem().getItem()).customArrow( arrow );
|
||||||
|
|
||||||
|
final double dX = target.getX() - getX();
|
||||||
|
final double dY = target.getY( 1.0 / 3.0 ) - arrow.getY();
|
||||||
|
final double dZ = target.getZ() - getZ();
|
||||||
|
final double dH = MathHelper.sqrt( dX * dX + dZ * dZ );
|
||||||
|
arrow.shoot( dX, dY + dH * 0.2, dZ, 1.6F,
|
||||||
|
getSpecialData().rangedAttackSpread * (1.0F - 0.2858F * level.getDifficulty().getId()) );
|
||||||
|
|
||||||
|
playSound( SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (random.nextFloat() * 0.4F + 0.8F) );
|
||||||
|
level.addFreshEntity( arrow );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return The arrow for this zombie to shoot. */
|
||||||
|
protected AbstractArrowEntity getArrow( ItemStack arrowItem, float damageMulti ) {
|
||||||
|
return getVariantArrow( ProjectileHelper.getMobArrow( this, arrowItem,
|
||||||
|
damageMulti * getSpecialData().rangedAttackDamage ), arrowItem, damageMulti );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Override to modify this entity's ranged attack projectile. */
|
||||||
|
protected AbstractArrowEntity getVariantArrow( AbstractArrowEntity arrow, ItemStack arrowItem, float damageMulti ) {
|
||||||
|
return arrow;
|
||||||
|
}
|
||||||
|
|
||||||
/** Called to melee attack the target. */
|
/** Called to melee attack the target. */
|
||||||
@Override
|
@Override
|
||||||
public boolean doHurtTarget( Entity target ) {
|
public boolean doHurtTarget( Entity target ) {
|
||||||
|
@ -108,6 +185,9 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
/** The parameter for special mob render scale. */
|
/** The parameter for special mob render scale. */
|
||||||
private static final DataParameter<Float> SCALE = EntityDataManager.defineId( _SpecialZombieEntity.class, DataSerializers.FLOAT );
|
private static final DataParameter<Float> SCALE = EntityDataManager.defineId( _SpecialZombieEntity.class, DataSerializers.FLOAT );
|
||||||
|
|
||||||
|
/** This entity's attack AI. */
|
||||||
|
private Goal currentAttackAI;
|
||||||
|
|
||||||
/** Called from the Entity.class constructor to define data watcher variables. */
|
/** Called from the Entity.class constructor to define data watcher variables. */
|
||||||
@Override
|
@Override
|
||||||
protected void defineSynchedData() {
|
protected void defineSynchedData() {
|
||||||
|
@ -120,10 +200,36 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
public ILivingEntityData finalizeSpawn( IServerWorld world, DifficultyInstance difficulty, SpawnReason spawnReason,
|
public ILivingEntityData finalizeSpawn( IServerWorld world, DifficultyInstance difficulty, SpawnReason spawnReason,
|
||||||
@Nullable ILivingEntityData groupData, @Nullable CompoundNBT eggTag ) {
|
@Nullable ILivingEntityData groupData, @Nullable CompoundNBT eggTag ) {
|
||||||
groupData = super.finalizeSpawn( world, difficulty, spawnReason, groupData, eggTag );
|
groupData = super.finalizeSpawn( world, difficulty, spawnReason, groupData, eggTag );
|
||||||
// TODO ranged attack
|
reassessWeaponGoal();
|
||||||
return groupData;
|
return groupData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Called to set the item equipped in a particular slot. */
|
||||||
|
@Override
|
||||||
|
public void setItemSlot( EquipmentSlotType slot, ItemStack item ) {
|
||||||
|
super.setItemSlot( slot, item );
|
||||||
|
if( !level.isClientSide ) reassessWeaponGoal();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called to set this entity's attack AI based on current equipment. */
|
||||||
|
public void reassessWeaponGoal() {
|
||||||
|
if( level != null && !level.isClientSide ) {
|
||||||
|
if( currentAttackAI != null ) goalSelector.removeGoal( currentAttackAI );
|
||||||
|
|
||||||
|
final SpecialMobData<_SpecialZombieEntity> data = getSpecialData();
|
||||||
|
final ItemStack weapon = getItemInHand( ProjectileHelper.getWeaponHoldingHand(
|
||||||
|
this, item -> item instanceof BowItem ) );
|
||||||
|
if( data.rangedAttackMaxRange > 0.0F && weapon.getItem() == Items.BOW ) {
|
||||||
|
currentAttackAI = new RangedBowAttackGoal<>( this, data.rangedWalkSpeed,
|
||||||
|
data.rangedAttackCooldown, data.rangedAttackMaxRange );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentAttackAI = new ZombieAttackGoal( this, 1.0, false );
|
||||||
|
}
|
||||||
|
goalSelector.addGoal( getVariantAttackPriority(), currentAttackAI );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//--------------- ISpecialMob Implementation ----------------
|
//--------------- ISpecialMob Implementation ----------------
|
||||||
|
|
||||||
|
@ -164,12 +270,12 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
/** @return The eye height of this entity when standing. */
|
/** @return The eye height of this entity when standing. */
|
||||||
@Override
|
@Override
|
||||||
protected float getStandingEyeHeight( Pose pose, EntitySize size ) {
|
protected float getStandingEyeHeight( Pose pose, EntitySize size ) {
|
||||||
return super.getStandingEyeHeight( pose, size ) * getSpecialData().getBaseScale() * (isBaby() ? 0.53448F : 1.0F);
|
return super.getStandingEyeHeight( pose, size ) * getSpecialData().getBaseScale();// * (isBaby() ? 0.53448F : 1.0F); - Handled in super
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Whether this entity is immune to fire damage. */
|
/** @return Whether this entity is immune to fire damage. */
|
||||||
@Override
|
@Override
|
||||||
public boolean fireImmune() { return specialData.isImmuneToFire(); }
|
public boolean fireImmune() { return getSpecialData().isImmuneToFire(); }
|
||||||
|
|
||||||
/** Sets this entity on fire for a specific duration. */
|
/** Sets this entity on fire for a specific duration. */
|
||||||
@Override
|
@Override
|
||||||
|
@ -177,6 +283,10 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
if( !getSpecialData().isImmuneToBurning() ) super.setRemainingFireTicks( ticks );
|
if( !getSpecialData().isImmuneToBurning() ) super.setRemainingFireTicks( ticks );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return True if this zombie burns in sunlight. */
|
||||||
|
@Override
|
||||||
|
protected boolean isSunSensitive() { return !getSpecialData().isImmuneToFire() && !getSpecialData().isImmuneToBurning(); }
|
||||||
|
|
||||||
/** @return True if this entity can be leashed. */
|
/** @return True if this entity can be leashed. */
|
||||||
@Override
|
@Override
|
||||||
public boolean canBeLeashed( PlayerEntity player ) { return !isLeashed() && getSpecialData().allowLeashing(); }
|
public boolean canBeLeashed( PlayerEntity player ) { return !isLeashed() && getSpecialData().allowLeashing(); }
|
||||||
|
@ -184,7 +294,7 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
/** Sets this entity 'stuck' inside a block, such as a cobweb or sweet berry bush. Mod blocks could use this as a speed boost. */
|
/** 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
|
@Override
|
||||||
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
public void makeStuckInBlock( BlockState block, Vector3d speedMulti ) {
|
||||||
if( specialData.canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
if( getSpecialData().canBeStuckIn( block ) ) super.makeStuckInBlock( block, speedMulti );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
/** @return Called when this mob falls. Calculates and applies fall damage. Returns false if canceled. */
|
||||||
|
@ -246,5 +356,7 @@ public class _SpecialZombieEntity extends ZombieEntity implements ISpecialMob<_S
|
||||||
|
|
||||||
getSpecialData().readFromNBT( saveTag );
|
getSpecialData().readFromNBT( saveTag );
|
||||||
readVariantSaveData( saveTag );
|
readVariantSaveData( saveTag );
|
||||||
|
|
||||||
|
reassessWeaponGoal();
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue