diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java index e18738a3ef..fb411ed488 100644 --- a/src/main/java/net/minecraft/server/EntityHorse.java +++ b/src/main/java/net/minecraft/server/EntityHorse.java @@ -3,10 +3,15 @@ package net.minecraft.server; import java.util.Iterator; import java.util.List; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; +import org.bukkit.event.entity.EntityDamageEvent; +// CraftBukkit end + public class EntityHorse extends EntityAnimal implements IInventoryListener { private static final IEntitySelector bu = new EntitySelectorHorse(); - private static final IAttribute attributeJumpStrength = (new AttributeRanged("horse.jumpStrength", 0.7D, 0.0D, 2.0D)).a("Jump Strength").a(true); + public static final IAttribute attributeJumpStrength = (new AttributeRanged("horse.jumpStrength", 0.7D, 0.0D, 2.0D)).a("Jump Strength").a(true); // CraftBukkit - private -> public private static final String[] bw = new String[] { null, "textures/entity/horse/armor/horse_armor_iron.png", "textures/entity/horse/armor/horse_armor_gold.png", "textures/entity/horse/armor/horse_armor_diamond.png"}; private static final String[] bx = new String[] { "", "meo", "goo", "dio"}; private static final int[] by = new int[] { 0, 5, 7, 11}; @@ -20,7 +25,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { public int bp; public int bq; protected boolean br; - private InventoryHorseChest inventoryChest; + public InventoryHorseChest inventoryChest; // CraftBukkit - private -> public private boolean bH; protected int bs; protected float bt; @@ -34,6 +39,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { private int bP; private String bQ; private String[] bR = new String[3]; + public int maxDomestication = 100; // CraftBukkit - store max domestication value public EntityHorse(World world) { super(world); @@ -281,9 +287,26 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { int i = MathHelper.f(f * 0.5F - 3.0F); if (i > 0) { - this.damageEntity(DamageSource.FALL, (float) i); + // CraftBukkit start + EntityDamageEvent event = CraftEventFactory.callEntityDamageEvent(null, this, EntityDamageEvent.DamageCause.FALL, i); + if (!event.isCancelled()) { + float damage = (float) event.getDamage(); + if (damage > 0) { + this.getBukkitEntity().setLastDamageCause(event); + this.damageEntity(DamageSource.FALL, damage); + } + } + if (this.passenger != null) { - this.passenger.damageEntity(DamageSource.FALL, (float) i); + EntityDamageEvent passengerEvent = CraftEventFactory.callEntityDamageEvent(null, this.passenger, EntityDamageEvent.DamageCause.FALL, i); + if (!passengerEvent.isCancelled() && this.passenger != null) { // Check again in case of plugin + float damage = (float) passengerEvent.getDamage(); + if (damage > 0) { + this.passenger.getBukkitEntity().setLastDamageCause(passengerEvent); + this.passenger.damageEntity(DamageSource.FALL, damage); + } + } + // CraftBukkit end } int j = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.locY - 0.2D - (double) this.lastYaw), MathHelper.floor(this.locZ)); @@ -299,10 +322,10 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { private int cG() { int i = this.getType(); - return this.hasChest() && (i == 1 || i == 2) ? 17 : 2; + return this.hasChest() /* && (i == 1 || i == 2) */ ? 17 : 2; // CraftBukkit - Remove type check } - private void cH() { + public void cH() { // CraftBukkit - private -> public InventoryHorseChest inventoryhorsechest = this.inventoryChest; this.inventoryChest = new InventoryHorseChest("HorseChest", this.cG()); @@ -467,7 +490,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { } public int cq() { - return 100; + return this.maxDomestication; // CraftBukkit - return stored max domestication instead of 100 } protected float aZ() { @@ -928,6 +951,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { nbttagcompound.setInt("Temper", this.getTemper()); nbttagcompound.setBoolean("Tame", this.isTame()); nbttagcompound.setString("OwnerName", this.getOwnerName()); + nbttagcompound.setInt("Bukkit.MaxDomestication", this.maxDomestication); // CraftBukkit if (this.hasChest()) { NBTTagList nbttaglist = new NBTTagList(); @@ -968,7 +992,11 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { if (nbttagcompound.hasKey("OwnerName")) { this.setOwnerName(nbttagcompound.getString("OwnerName")); } - + // CraftBukkit start + if (nbttagcompound.hasKey("Bukkit.MaxDomestication")) { + this.maxDomestication = nbttagcompound.getInt("Bukkit.MaxDomestication"); + } + // CraftBukkit end AttributeInstance attributeinstance = this.aW().a("Speed"); if (attributeinstance != null) { @@ -1138,18 +1166,25 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { public void u(int i) { if (this.co()) { + // CraftBukkit start - fire HorseJumpEvent, use event power if (i < 0) { i = 0; - } else { - this.bI = true; - this.cO(); } + float power; if (i >= 90) { - this.bt = 1.0F; + power = 1.0F; } else { - this.bt = 0.4F + 0.4F * (float) i / 90.0F; + power = 0.4F + 0.4F * (float) i / 90.0F; } + + org.bukkit.event.entity.HorseJumpEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callHorseJumpEvent(this, power); + if (!event.isCancelled()) { + this.bI = true; + this.cO(); + this.bt = event.getPower(); + } + // CraftBukkit end } } diff --git a/src/main/java/net/minecraft/server/PathfinderGoalTame.java b/src/main/java/net/minecraft/server/PathfinderGoalTame.java index 889dc719c4..8fde2e114a 100644 --- a/src/main/java/net/minecraft/server/PathfinderGoalTame.java +++ b/src/main/java/net/minecraft/server/PathfinderGoalTame.java @@ -45,7 +45,8 @@ public class PathfinderGoalTame extends PathfinderGoal { int i = this.entity.getTemper(); int j = this.entity.cq(); - if (j > 0 && this.entity.aC().nextInt(j) < i) { + // CraftBukkit + if (j > 0 && this.entity.aC().nextInt(j) < i && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.entity, (EntityHuman) this.entity.passenger).isCancelled() && this.entity.passenger instanceof EntityHuman) { this.entity.g((EntityHuman) this.entity.passenger); this.entity.world.broadcastEntityEffect(this.entity, (byte) 7); return; @@ -54,7 +55,7 @@ public class PathfinderGoalTame extends PathfinderGoal { this.entity.t(5); } - this.entity.passenger.mount((Entity) null); + if (this.entity.passenger != null) this.entity.passenger.mount((Entity) null); // CraftBukkit - Check for null this.entity.passenger = null; this.entity.cD(); this.entity.world.broadcastEntityEffect(this.entity, (byte) 6); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index e06e23b4de..75b1fb2ec8 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -906,6 +906,8 @@ public class CraftWorld implements World { // need a net server handler for this one } else if (Sheep.class.isAssignableFrom(clazz)) { entity = new EntitySheep(world); + } else if (Horse.class.isAssignableFrom(clazz)) { + entity = new EntityHorse(world); } else if (Skeleton.class.isAssignableFrom(clazz)) { entity = new EntitySkeleton(world); } else if (Slime.class.isAssignableFrom(clazz)) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 97f3c1d5e6..4aec8e9e2b 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -51,6 +51,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { else if (entity instanceof EntityOcelot) { return new CraftOcelot(server, (EntityOcelot) entity); } } else if (entity instanceof EntitySheep) { return new CraftSheep(server, (EntitySheep) entity); } + else if (entity instanceof EntityHorse) { return new CraftHorse(server, (EntityHorse) entity); } else { return new CraftAnimals(server, (EntityAnimal) entity); } } // Monsters diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java index 4dd771267c..b0da3b9cb8 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java @@ -1,23 +1,136 @@ -package org.bukkit.craftbukkit.entity; - -import net.minecraft.server.EntityAnimal; - -import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.EntityType; -import org.bukkit.entity.Horse; - -public class CraftHorse extends CraftAnimals implements Horse { - - public CraftHorse(CraftServer server, EntityAnimal entity) { - super(server, entity); - } - - @Override - public String toString() { - return "CraftHorse"; - } - - public EntityType getType() { - return EntityType.HORSE; - } -} +package org.bukkit.craftbukkit.entity; + +import net.minecraft.server.EntityHorse; +import org.apache.commons.lang.Validate; +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.craftbukkit.inventory.CraftInventoryHorse; +import org.bukkit.entity.AnimalTamer; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; +import org.bukkit.inventory.HorseInventory; + +public class CraftHorse extends CraftAnimals implements Horse { + + public CraftHorse(CraftServer server, EntityHorse entity) { + super(server, entity); + } + + @Override + public EntityHorse getHandle() { + return (EntityHorse) entity; + } + + public Variant getVariant() { + return Variant.values()[getHandle().getType()]; + } + + public void setVariant(Variant variant) { + Validate.notNull(variant, "Variant cannot be null"); + getHandle().setType(variant.ordinal()); + } + + public Color getColor() { + return Color.values()[getHandle().getVariant() & 0xFF]; + } + + public void setColor(Color color) { + Validate.notNull(color, "Color cannot be null"); + getHandle().setVariant(color.ordinal() & 0xFF | getStyle().ordinal() << 8); + } + + public Style getStyle() { + return Style.values()[getHandle().getVariant() >>> 8]; + } + + public void setStyle(Style style) { + Validate.notNull(style, "Style cannot be null"); + getHandle().setVariant(getColor().ordinal() & 0xFF | style.ordinal() << 8); + } + + public boolean isCarryingChest() { + return getHandle().hasChest(); + } + + public void setCarryingChest(boolean chest) { + if (chest == isCarryingChest()) return; + getHandle().setHasChest(chest); + getHandle().cH(); // Should be loadChest + } + + public int getDomestication() { + return getHandle().getTemper(); + } + + public void setDomestication(int value) { + Validate.isTrue(value >= 0, "Domestication cannot be less than zero"); + Validate.isTrue(value <= getMaxDomestication(), "Domestication cannot be greater than the max domestication"); + getHandle().setTemper(value); + } + + public int getMaxDomestication() { + return getHandle().cq(); // Should be getMaxDomestication + } + + public void setMaxDomestication(int value) { + Validate.isTrue(value > 0, "Max domestication cannot be zero or less"); + getHandle().maxDomestication = value; + } + + public double getJumpStrength() { + return getHandle().getJumpStrength(); + } + + public void setJumpStrength(double strength) { + Validate.isTrue(strength >= 0, "Jump strength cannot be less than zero"); + getHandle().getAttributeInstance(EntityHorse.attributeJumpStrength).setValue(strength); + } + + @Override + public boolean isTamed() { + return getHandle().isTame(); + } + + @Override + public void setTamed(boolean tamed) { + getHandle().setTame(tamed); + } + + @Override + public AnimalTamer getOwner() { + if (getOwnerName() == null || "".equals(getOwnerName())) return null; + return getServer().getOfflinePlayer(getOwnerName()); + } + + @Override + public void setOwner(AnimalTamer owner) { + if (owner != null && !"".equals(owner.getName())) { + setTamed(true); + getHandle().setPathEntity(null); + setOwnerName(owner.getName()); + } else { + setTamed(false); + setOwnerName(""); + } + } + + public String getOwnerName() { + return getHandle().getOwnerName(); + } + + public void setOwnerName(String name) { + getHandle().setOwnerName(name); + } + + public HorseInventory getInventory() { + return new CraftInventoryHorse(getHandle().inventoryChest); + } + + @Override + public String toString() { + return "CraftHorse{variant=" + getVariant() + ", owner=" + getOwner() + '}'; + } + + public EntityType getType() { + return EntityType.HORSE; + } +} diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 9986b7ac7f..6db7b9ba30 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -48,6 +48,7 @@ import org.bukkit.entity.AnimalTamer; import org.bukkit.entity.Arrow; import org.bukkit.entity.Creeper; import org.bukkit.entity.EntityType; +import org.bukkit.entity.Horse; import org.bukkit.entity.LightningStrike; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Pig; @@ -492,6 +493,12 @@ public class CraftEventFactory { return event; } + public static HorseJumpEvent callHorseJumpEvent(Entity horse, float power) { + HorseJumpEvent event = new HorseJumpEvent((Horse) horse.getBukkitEntity(), power); + horse.getBukkitEntity().getServer().getPluginManager().callEvent(event); + return event; + } + public static EntityChangeBlockEvent callEntityChangeBlockEvent(org.bukkit.entity.Entity entity, Block block, Material material) { return callEntityChangeBlockEvent(entity, block, material, 0); } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java index bb5222eb4b..5adbd7437e 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java @@ -1,25 +1,28 @@ package org.bukkit.craftbukkit.inventory; import net.minecraft.server.IInventory; +import org.bukkit.inventory.HorseInventory; +import org.bukkit.inventory.ItemStack; -public class CraftInventoryHorse extends CraftInventory { - private final IInventory resultInventory = null; +public class CraftInventoryHorse extends CraftInventory implements HorseInventory { public CraftInventoryHorse(IInventory inventory) { super(inventory); } - public IInventory getResultInventory() { - return resultInventory; + public ItemStack getSaddle() { + return getItem(0); } - public IInventory getIngredientsInventory() { - return inventory; + public ItemStack getArmor() { + return getItem(1); } - @Override - public int getSize() { - //return getResultInventory().getSize() + getIngredientsInventory().getSize(); - return getIngredientsInventory().getSize(); + public void setSaddle(ItemStack stack) { + setItem(0, stack); + } + + public void setArmor(ItemStack stack) { + setItem(1, stack); } }