Merge branch '1.12.2' into 1.12.2-dev
This commit is contained in:
@@ -3,7 +3,6 @@ package electroblob.wizardry.entity.living;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
@@ -119,10 +118,10 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
|| (entity instanceof ISummonedCreature || entity instanceof EntityWizard
|
||||
// ... or in the whitelist ...
|
||||
|| Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT)))
|
||||
.contains(EntityList.getKey(entity.getClass())))
|
||||
// ... and isn't in the blacklist ...
|
||||
&& !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){
|
||||
.contains(EntityList.getKey(entity.getClass()))){
|
||||
// ... it can be attacked.
|
||||
return true;
|
||||
}
|
||||
@@ -266,6 +265,21 @@ public class EntityEvilWizard extends EntityMob implements ISpellCaster, IEntity
|
||||
(NBTTagInt tag) -> Spell.get(tag.getInt()));
|
||||
this.hasTower = nbt.getBoolean("hasTower");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSpawnedInChunk(){
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getCanSpawnHere(){
|
||||
// Evil wizards can only spawn in the specified dimensions
|
||||
for(int id : Wizardry.settings.evilWizardDimensions){
|
||||
if(this.dimension == id) return super.getCanSpawnHere();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn(){
|
||||
|
||||
@@ -18,6 +18,7 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.util.text.translation.I18n;
|
||||
@@ -52,13 +53,22 @@ public class EntitySpiritHorse extends EntityHorse {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getExperiencePoints(EntityPlayer p_70693_1_){
|
||||
protected int getExperiencePoints(EntityPlayer player){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem(){
|
||||
protected boolean canDropLoot(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getLootTable(){
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.DamageSource;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
import net.minecraft.util.text.TextComponentTranslation;
|
||||
import net.minecraft.world.DifficultyInstance;
|
||||
@@ -71,11 +72,6 @@ public class EntitySpiritWolf extends EntityWolf {
|
||||
super.onDeath(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getExperiencePoints(EntityPlayer p_70693_1_){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata){
|
||||
|
||||
@@ -151,11 +147,26 @@ public class EntitySpiritWolf extends EntityWolf {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getExperiencePoints(EntityPlayer player){
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDropLoot(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Item getDropItem(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getLootTable(){
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
if(getOwner() != null){
|
||||
|
||||
@@ -5,10 +5,11 @@ import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import electroblob.wizardry.Wizardry;
|
||||
@@ -29,25 +30,24 @@ import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityAgeable;
|
||||
import net.minecraft.entity.EntityCreature;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.entity.EntityLiving;
|
||||
import net.minecraft.entity.IEntityLivingData;
|
||||
import net.minecraft.entity.IMerchant;
|
||||
import net.minecraft.entity.INpc;
|
||||
import net.minecraft.entity.SharedMonsterAttributes;
|
||||
import net.minecraft.entity.ai.EntityAIBase;
|
||||
import net.minecraft.entity.ai.EntityAIHurtByTarget;
|
||||
import net.minecraft.entity.ai.EntityAILookAtTradePlayer;
|
||||
import net.minecraft.entity.ai.EntityAIMoveTowardsRestriction;
|
||||
import net.minecraft.entity.ai.EntityAINearestAttackableTarget;
|
||||
import net.minecraft.entity.ai.EntityAIOpenDoor;
|
||||
import net.minecraft.entity.ai.EntityAIRestrictOpenDoor;
|
||||
import net.minecraft.entity.ai.EntityAISwimming;
|
||||
import net.minecraft.entity.ai.EntityAITradePlayer;
|
||||
import net.minecraft.entity.ai.EntityAIWander;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest;
|
||||
import net.minecraft.entity.ai.EntityAIWatchClosest2;
|
||||
import net.minecraft.entity.effect.EntityLightningBolt;
|
||||
import net.minecraft.entity.monster.IMob;
|
||||
import net.minecraft.entity.passive.EntityVillager;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.init.Blocks;
|
||||
import net.minecraft.init.Items;
|
||||
@@ -77,23 +77,12 @@ import net.minecraftforge.event.world.BlockEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
import net.minecraftforge.fml.common.registry.VillagerRegistry.VillagerProfession;
|
||||
import net.minecraftforge.fml.relauncher.Side;
|
||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
@Mod.EventBusSubscriber
|
||||
public class EntityWizard extends EntityVillager implements ISpellCaster, IEntityAdditionalSpawnData {
|
||||
|
||||
/* After much debugging, the error in the compiled mod (outside of eclipse) was traced back to this class,
|
||||
* specifically the methods copied in from EntityVillager when I changed this class to extend it. This figures,
|
||||
* since I had 1.2.1 working just fine before I did that, and it was the only thing I changed. Apparently, methods
|
||||
* and fields with obfuscated names like func_129090_a can cause problems when compiled. One of the ones here was
|
||||
* renamed and the other deleted since it was never called. Watch out for this in future (unless, of course, they
|
||||
* are overriding something, in which case it should be fine). */
|
||||
|
||||
// Extending EntityVillager turned out to be a pretty neat thing to do, since now zombies will attack wizards
|
||||
// TODO: Perhaps we should be implementing IMerchant now instead?
|
||||
public class EntityWizard extends EntityCreature implements INpc, IMerchant, ISpellCaster, IEntityAdditionalSpawnData {
|
||||
|
||||
private EntityAIAttackSpell spellCastingAI = new EntityAIAttackSpell(this, 0.5D, 14.0F, 30, 50);
|
||||
|
||||
@@ -102,19 +91,21 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
/** The entity selector passed into the new AI methods. */
|
||||
protected Predicate<Entity> targetSelector;
|
||||
|
||||
/** Copy of EntityVillager's buyingList, renamed to avoid confusion. */
|
||||
/** The wizard's trades. */
|
||||
private MerchantRecipeList trades;
|
||||
/** The wizard's current customer. */
|
||||
@Nullable
|
||||
private EntityPlayer customer;
|
||||
|
||||
private int timeUntilReset;
|
||||
|
||||
/** addDefaultEquipmentAndRecipies is called if this is true */
|
||||
private boolean updateRecipes;
|
||||
|
||||
/** Data parameter for the cooldown time for wizards healing themselves. */
|
||||
private static final DataParameter<Integer> HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
private static final DataParameter<Integer> HEAL_COOLDOWN = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
/** Data parameter for the wizard's element. */
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityWizard.class,
|
||||
DataSerializers.VARINT);
|
||||
private static final DataParameter<Integer> ELEMENT = EntityDataManager.createKey(EntityWizard.class, DataSerializers.VARINT);
|
||||
|
||||
// Field implementations
|
||||
private List<Spell> spells = new ArrayList<Spell>(4);
|
||||
@@ -141,6 +132,8 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
protected void initEntityAI(){
|
||||
|
||||
this.tasks.addTask(0, new EntityAISwimming(this));
|
||||
// Why would you go to the effort of making the IMerchant interface and then have the AI classes only accept
|
||||
// EntityVillager? N
|
||||
this.tasks.addTask(1, new EntityAITradePlayer(this));
|
||||
this.tasks.addTask(1, new EntityAILookAtTradePlayer(this));
|
||||
this.tasks.addTask(4, new EntityAIRestrictOpenDoor(this));
|
||||
@@ -167,7 +160,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
// ... and isn't in the blacklist ...
|
||||
&& !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){
|
||||
// ... it can be attacked.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -225,6 +217,55 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
return this.continuousSpell;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomer(EntityPlayer player){
|
||||
this.customer = player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityPlayer getCustomer(){
|
||||
return this.customer;
|
||||
}
|
||||
|
||||
public boolean isTrading(){
|
||||
return this.getCustomer() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verifySellingItem(ItemStack stack){
|
||||
// Copied from EntityVillager
|
||||
if(!this.world.isRemote && this.livingSoundTime > -this.getTalkInterval() + 20){
|
||||
this.livingSoundTime = -this.getTalkInterval();
|
||||
this.playSound(stack.isEmpty() ? SoundEvents.ENTITY_VILLAGER_NO : SoundEvents.ENTITY_VILLAGER_YES, this.getSoundVolume(), this.getSoundPitch());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWorld(){
|
||||
return this.world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos getPos(){
|
||||
return new BlockPos(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SideOnly(Side.CLIENT)
|
||||
public void setRecipes(MerchantRecipeList recipeList){
|
||||
// Apparently nothing goes here, and nothing's here in EntityVillager either...
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
return this.getElement().getWizardName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLivingUpdate(){
|
||||
|
||||
@@ -304,8 +345,7 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
}
|
||||
}
|
||||
|
||||
// Super call removed because EntityVillager's version does things I don't want and the next one up is
|
||||
// in EntityLivingBase and does nothing.
|
||||
super.updateAITasks(); // This actually does nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -341,11 +381,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ITextComponent getDisplayName(){
|
||||
return this.getElement().getWizardName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeEntityToNBT(NBTTagCompound nbt){
|
||||
|
||||
@@ -384,16 +419,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
nbt.getTagList("towerBlocks", NBT.TAG_LONG), (NBTTagLong tag) -> BlockPos.fromLong(tag.getLong())));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canDespawn(){
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrading(){
|
||||
return this.getCustomer() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void useRecipe(MerchantRecipe merchantrecipe){
|
||||
|
||||
@@ -661,11 +686,6 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
return new ItemStack(Blocks.STONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProfession(VillagerProfession prof){
|
||||
// Disables Forge's stuff.
|
||||
}
|
||||
|
||||
@Override
|
||||
public IEntityLivingData onInitialSpawn(DifficultyInstance difficulty, IEntityLivingData livingdata){
|
||||
|
||||
@@ -823,49 +843,72 @@ public class EntityWizard extends EntityVillager implements ISpellCaster, IEntit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copied from their respective AI classes
|
||||
|
||||
public static class EntityAILookAtTradePlayer extends EntityAIWatchClosest {
|
||||
|
||||
private final EntityWizard wizard;
|
||||
|
||||
// EntityVillager overrides (that don't add features)
|
||||
public EntityAILookAtTradePlayer(EntityWizard wizard){
|
||||
super(wizard, EntityPlayer.class, 8.0F);
|
||||
this.wizard = wizard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMating(){
|
||||
return false;
|
||||
@Override
|
||||
public boolean shouldExecute(){
|
||||
if(this.wizard.isTrading()){
|
||||
this.closestEntity = this.wizard.getCustomer();
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class EntityAITradePlayer extends EntityAIBase {
|
||||
|
||||
private final EntityWizard wizard;
|
||||
|
||||
@Override
|
||||
public void setMating(boolean p_70947_1_){
|
||||
}
|
||||
public EntityAITradePlayer(EntityWizard wizard){
|
||||
this.wizard = wizard;
|
||||
this.setMutexBits(5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlaying(boolean p_70939_1_){
|
||||
}
|
||||
@Override
|
||||
public boolean shouldExecute(){
|
||||
|
||||
if(!this.wizard.isEntityAlive()){
|
||||
return false;
|
||||
}else if(this.wizard.isInWater()){
|
||||
return false;
|
||||
}else if(!this.wizard.onGround){
|
||||
return false;
|
||||
}else if(this.wizard.velocityChanged){
|
||||
return false;
|
||||
}else{
|
||||
|
||||
EntityPlayer entityplayer = this.wizard.getCustomer();
|
||||
|
||||
@Override
|
||||
public boolean isPlaying(){
|
||||
return false;
|
||||
}
|
||||
if(entityplayer == null){
|
||||
return false;
|
||||
}else if(this.wizard.getDistanceSq(entityplayer) > 16.0D){
|
||||
return false;
|
||||
}else{
|
||||
return entityplayer.openContainer != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLookingForHome(){
|
||||
}
|
||||
@Override
|
||||
public void startExecuting(){
|
||||
this.wizard.getNavigator().clearPath();
|
||||
}
|
||||
|
||||
// Doesn't say it, but this is in fact nullable.
|
||||
@Override
|
||||
public EntityVillager createChild(EntityAgeable par1EntityAgeable){
|
||||
return null;
|
||||
}
|
||||
|
||||
@SideOnly(Side.CLIENT)
|
||||
@Override
|
||||
public void setRecipes(MerchantRecipeList par1MerchantRecipeList){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStruckByLightning(EntityLightningBolt lightningBolt){
|
||||
// Restores the normal behaviour, replacing EntityVillager's witch conversion.
|
||||
this.attackEntityFrom(DamageSource.LIGHTNING_BOLT, 5.0F);
|
||||
// Entity's version does something strange with the private fire variable, but since I don't have access this
|
||||
// will probably be fine.
|
||||
this.setFire(8);
|
||||
@Override
|
||||
public void resetTask(){
|
||||
this.wizard.setCustomer((EntityPlayer)null);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package electroblob.wizardry.entity.living;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@@ -183,18 +182,28 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
|
||||
if(!entity.isInvisible() && isValidTarget(entity)){
|
||||
|
||||
// ... and is a player, they can be attacked, since players can't be in the whitelist or the
|
||||
// blacklist.
|
||||
if(entity instanceof EntityPlayer) return true;
|
||||
// blacklist ...
|
||||
if(entity instanceof EntityPlayer){
|
||||
// ... unless the creature was summoned by a good wizard who the player has not angered.
|
||||
if(getCaster() instanceof EntityWizard){
|
||||
if(((EntityWizard)getCaster()).getRevengeTarget() != entity
|
||||
&& ((EntityWizard)getCaster()).getAttackTarget() != entity) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ... and is a mob, a summoned creature, a wizard ...
|
||||
if((entity instanceof IMob || entity instanceof ISummonedCreature
|
||||
|| (entity instanceof EntityWizard && !(getCaster() instanceof EntityWizard))
|
||||
// ... or in the whitelist ...
|
||||
|| Arrays.asList(Wizardry.settings.summonedCreatureTargetsWhitelist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT)))
|
||||
.contains(EntityList.getKey(entity.getClass())))
|
||||
// ... and isn't in the blacklist ...
|
||||
&& !Arrays.asList(Wizardry.settings.summonedCreatureTargetsBlacklist)
|
||||
.contains(EntityList.getEntityString(entity).toLowerCase(Locale.ROOT))){
|
||||
.contains(EntityList.getKey(entity.getClass()))){
|
||||
// ... it can be attacked.
|
||||
return true;
|
||||
}
|
||||
@@ -364,11 +373,18 @@ public interface ISummonedCreature extends IEntityAdditionalSpawnData {
|
||||
if(event.getSource().isFireDamage()) newSource.setFireDamage();
|
||||
if(event.getSource().isProjectile()) newSource.setProjectile();
|
||||
|
||||
// For some reason Minecraft calculates knockback relative to DamageSource#getEntity. In vanilla this
|
||||
// For some reason Minecraft calculates knockback relative to DamageSource#getTrueSource. In vanilla this
|
||||
// is unnoticeable, but it looks a bit weird with summoned creatures involved - so this fixes that.
|
||||
if(WizardryUtilities.attackEntityWithoutKnockback(event.getEntity(), newSource, event.getAmount())){
|
||||
// Using event.getSource().getTrueSource() as this means the target is knocked back from the minion
|
||||
WizardryUtilities.applyStandardKnockback(event.getSource().getTrueSource(), event.getEntityLiving());
|
||||
((ISummonedCreature)event.getSource().getTrueSource()).onSuccessfulAttack(event.getEntityLiving());
|
||||
// If the target revenge-targeted the summoner, make it revenge-target the minion instead
|
||||
// (if it didn't revenge-target, do nothing)
|
||||
if(event.getEntityLiving().getRevengeTarget() == summoner
|
||||
&& event.getSource().getTrueSource() instanceof EntityLivingBase){
|
||||
event.getEntityLiving().setRevengeTarget((EntityLivingBase)event.getSource().getTrueSource());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
|
||||
/**
|
||||
* Same as {@link EntityMagicProjectile}, but with an additional blast multiplier field which is synced and saved to
|
||||
@@ -13,7 +12,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
* @author Electroblob
|
||||
* @since Wizardry 1.2
|
||||
*/
|
||||
public abstract class EntityBomb extends EntityMagicProjectile implements IEntityAdditionalSpawnData {
|
||||
public abstract class EntityBomb extends EntityMagicProjectile {
|
||||
|
||||
/** The entity blast multiplier. This is now synced and saved centrally from {@link EntityBomb}. */
|
||||
public float blastMultiplier = 1.0f;
|
||||
@@ -37,11 +36,13 @@ public abstract class EntityBomb extends EntityMagicProjectile implements IEntit
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf buffer){
|
||||
super.writeSpawnData(buffer);
|
||||
buffer.writeFloat(blastMultiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf buffer){
|
||||
super.readSpawnData(buffer);
|
||||
blastMultiplier = buffer.readFloat();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package electroblob.wizardry.entity.projectile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.projectile.EntityThrowable;
|
||||
@@ -25,7 +24,7 @@ import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||
* @author Electroblob
|
||||
* @see EntityBomb
|
||||
*/
|
||||
public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
public abstract class EntityMagicProjectile extends EntityThrowable implements IEntityAdditionalSpawnData {
|
||||
|
||||
public float damageMultiplier = 1.0f;
|
||||
|
||||
@@ -42,6 +41,8 @@ public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
// This is the standard set of parameters for this method, used by snowballs and ender pearls amongst others.
|
||||
this.shoot(thrower, thrower.rotationPitch, thrower.rotationYaw, 0.0f, this.getSpeed(), 1.0f);
|
||||
this.damageMultiplier = damageMultiplier;
|
||||
// Mojang's 'fix' for the projectile-hitting-thrower bug actually made the problem worse, hence the following line.
|
||||
this.ignoreEntity = thrower;
|
||||
}
|
||||
|
||||
public EntityMagicProjectile(World world, double x, double y, double z){
|
||||
@@ -78,17 +79,17 @@ public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
// inside a mob using commands, it wouldn't hit that mob. This is so minor that it's not worth sending a packet
|
||||
// for, though it may become more noticeable if spells firing from blocks are added.
|
||||
// TODO: Investigate whether this is still necessary in 1.12
|
||||
if(this.world.isRemote){
|
||||
|
||||
List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(this.motionX, this.motionY, this.motionZ).grow(1.0D));
|
||||
|
||||
for(Entity entity : list){ // Why does vanilla still not use a for-each loop?
|
||||
if(entity.canBeCollidedWith() && this.ticksExisted < 2 && this.ignoreEntity == null){
|
||||
this.ignoreEntity = entity;
|
||||
}
|
||||
}
|
||||
// Pretty sure EntityThrowable handles the rest.
|
||||
}
|
||||
// if(this.world.isRemote){
|
||||
//
|
||||
// List<Entity> list = this.world.getEntitiesWithinAABBExcludingEntity(this, this.getEntityBoundingBox().expand(this.motionX, this.motionY, this.motionZ).grow(1.0D));
|
||||
//
|
||||
// for(Entity entity : list){ // Why does vanilla still not use a for-each loop?
|
||||
// if(entity.canBeCollidedWith() && this.ticksExisted < 2 && this.ignoreEntity == null){
|
||||
// this.ignoreEntity = entity;
|
||||
// }
|
||||
// }
|
||||
// // Pretty sure EntityThrowable handles the rest.
|
||||
// }
|
||||
|
||||
super.onUpdate();
|
||||
}
|
||||
@@ -105,4 +106,16 @@ public abstract class EntityMagicProjectile extends EntityThrowable {
|
||||
nbttagcompound.setFloat("damageMultiplier", damageMultiplier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
data.writeInt(this.getThrower().getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf data){
|
||||
Entity entity = this.world.getEntityByID(data.readInt());
|
||||
if(entity instanceof EntityLivingBase) this.thrower = (EntityLivingBase)entity;
|
||||
this.ignoreEntity = this.thrower;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import electroblob.wizardry.util.MagicDamage.DamageType;
|
||||
import electroblob.wizardry.util.ParticleBuilder;
|
||||
import electroblob.wizardry.util.ParticleBuilder.Type;
|
||||
import electroblob.wizardry.util.WizardryUtilities;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityLivingBase;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
@@ -20,9 +19,6 @@ import net.minecraft.world.World;
|
||||
|
||||
public class EntitySparkBomb extends EntityBomb {
|
||||
|
||||
/** For client use, because thrower field is not visible. */
|
||||
private int casterID;
|
||||
|
||||
public EntitySparkBomb(World par1World){
|
||||
super(par1World);
|
||||
}
|
||||
@@ -85,7 +81,7 @@ public class EntitySparkBomb extends EntityBomb {
|
||||
&& ((EntityPlayer)targets.get(i)).capabilities.isCreativeMode);
|
||||
|
||||
// Detects (client side) if target is the thrower, to stop particles being spawned around them.
|
||||
if(flag && world.isRemote && targets.get(i).getEntityId() == this.casterID) flag = false;
|
||||
//if(flag && world.isRemote && targets.get(i).getEntityId() == this.casterID) flag = false;
|
||||
|
||||
if(flag){
|
||||
|
||||
@@ -121,16 +117,4 @@ public class EntitySparkBomb extends EntityBomb {
|
||||
|
||||
this.setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSpawnData(ByteBuf data){
|
||||
super.writeSpawnData(data);
|
||||
data.writeInt(this.getThrower().getEntityId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readSpawnData(ByteBuf data){
|
||||
super.readSpawnData(data);
|
||||
this.casterID = data.readInt();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user